package controllers

import (
	"bytes"
	"cvevulner/common"
	"cvevulner/cve-timed-task/tabletask"
	"cvevulner/models"
	"cvevulner/task"
	"cvevulner/taskhandler"
	"cvevulner/util"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"
	"io/ioutil"
	"net/http"
	"os"
	"regexp"
	"strconv"
	"strings"
	"sync"
	"time"
)

var (
	//GiteeUserAgent gitee hook request flag
	GiteeUserAgent = "git-oschina-hook"
	//XGiteeToken password or sign
	XGiteeToken = "X-Gitee-Token"
	//XGIteeEventType webhook event type
	XGIteeEventType = "X-Gitee-Event"
	//NoteHookType type of comment
	NoteHookType = "Note Hook"
	//PullReqHookType type of pull request
	PullReqHookType = "Merge Request Hook"
	//PushTagHookType type of push or tag
	PushTagHookType = "Tag Push Hook"
	//IssueHookType type of issue
	IssueHookType = "Issue Hook"
)

const (
	//CommentAnalysisCplTpl complete comment analysis reply template
	CommentAnalysisCplTpl = "@%v %v"
	//ReviewPrivateLettersTpl send private review letters template
	ReviewPrivateLettersTpl = `%s(%s)analysis is over,CVEScore:%v;OpenEulerScore:%v.Please review!`
	//ReviewRejectScore reply the review reject template
	ReviewRejectScore = `@%v you submit issue score audit failed(reject by %v),Please re-analyze and submit!`
	//ReviewApproveScore replay the review approve template
	ReviewApproveScore = `@%v you submit issue score audit success(approved by %v),You can proceed to the next step!`
	//CommentReviewTpl comment review template
	CommentReviewTpl = `%v The CVE score needs to be reviewed (the review instruction /approve or /reject means agreement and rejection).`
	//IssueRejectState issue state rejected
	IssueRejectState = "rejected"
	//IssueCloseState issue state closed
	IssueCloseState = "closed"
	//IssueProgressState issue  state progressing
	IssueProgressState = "progressing"
	//IssueOpenState issue state open
	IssueOpenState = "open"
	//AnalysisComplete issue analysis complete comment
	AnalysisComplete = "@%v 经过 cve-manager 解析, 已分析的内容如下表所示:\n"
	// Content review tips
	ContentReview = "%v 请完成以下操作:\n"
	// Not filling in the correct format
	IssueErroFormat = "%v 经过 cve-manager 解析, 填写openEuler评分未通过安全组成员审核需要再次在评论区提交评分,通过审核后才能关闭ISSUE."
	// Remind the security group to review
	CommentReviewRemind = "%v 经过 cve-manager 解析 openEuler评分 已改变 需要您及时进行审核,以便maintainer进行后续操作."
	// Review private messages
	CommentPrivateReview = "%v 仓库的CVE和安全问题的ISSUE,需要您进行审核,CVE编号: %v"
	// Rating review failed
	CommentPrivateOpenEuler = "%v 仓库的CVE和安全问题的ISSUE, CVE编号: %v, 填写openEuler评分未通过安全组成员审核需要再次在评论区提交评分,通过审核后才能关闭ISSUE."
	// Review reminder
	CommentReviewRemindMaintainer = "@%v 经过 cve-manager 解析 openEuler评分 已改变 需要等待安全组成员审核通过以后, 才能进行后续操作."
	CIssueType                    = "CVE和安全问题"
	HasCreateIssue                = "@%v 当前CVE:%v 已经创建过对应的ISSUE, 请不要重复创建ISSUE, cve-manager 只会识别之前的ISSUE,不会对当前ISSUE进行处理."
	CommentCheckVersion           = "@%v 请确认分支: %v 受影响/不受影响."
	// rejected or upend
	CommentRejectedState = `@%v 当前issue状态为: %v,请先修改issue状态, 否则评论无法被识别.`
	// Get cve information comment
	CommentGetNvdCveSuccess = `@%v CVE信息从NVD同步成功, 稍后请重新加载页面.`
	CommentGetNvdCveFailed  = `@%v CVE信息从NVD同步失败, 请稍后重试, 或者数据源不存在.`
	CommentRepeatIssue      = `%v 请检查当前: %v,是否重复创建, issue编号： %v, 重复创建的issue,将不会被再次识别.`
)

var comLock sync.Mutex

//HookEventControllers gitee hook callback
type HookEventControllers struct {
	beego.Controller
}

type AgencyPrams struct {
	CveUrl   string
	PatchUrl string
}

//Post handle gitee webhook
// @router / [post]
func (c *HookEventControllers) Post() {
	if ok := c.isLegitimateHookEvent(); !ok {
		c.Ctx.ResponseWriter.WriteHeader(406)
		c.Ctx.WriteString("Illegal incident, discarded")
		return
	}
	eventType := c.Ctx.Request.Header.Get(XGIteeEventType)
	c.Ctx.ResponseWriter.WriteHeader(200)
	c.Ctx.WriteString("Event received: " + eventType)
	switch eventType {
	case NoteHookType: //handle comment hook data
		c.handleNoteDate()
	case PullReqHookType:
		c.handlePullReq()
	case IssueHookType:
		c.handleIssue()
	case PushTagHookType:
		c.handlePushTag()
	default:
		logs.Info(eventType)
	}
}

//isLegitimateHookEvent according to gitee doc judge
func (c *HookEventControllers) isLegitimateHookEvent() (ok bool) {
	ok = true
	//judge user agent
	uAgent := c.Ctx.Request.Header.Get("User-Agent")
	if uAgent != GiteeUserAgent {
		ok = false
	}
	ctType := c.Ctx.Request.Header.Get("Content-Type")
	if "application/json" != ctType {
		ok = false
	}
	//judge hook password
	xToken := c.Ctx.Request.Header.Get(XGiteeToken)
	//logs.Info(xToken)
	hookPwd := beego.AppConfig.String("hook::hookpwd")
	if xToken != hookPwd {
		logs.Error("hookPwd Err, xToken: ", xToken)
	}
	return
}

func (c *HookEventControllers) handleNoteDate() {
	var hookNote models.CommentPayload
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &hookNote)
	if err != nil {
		logs.Error(err, "\n, ", string(c.Ctx.Input.RequestBody))
		return
	}
	hookPwd := beego.AppConfig.String("hook::hookpwd")
	hookNote.Password = util.TrimString(hookNote.Password)
	hookPwd = util.TrimString(hookPwd)
	if hookNote.Action == "comment" && hookNote.NoteableType == "Issue" && hookNote.Password == hookPwd {
		logs.Info(string(c.Ctx.Input.RequestBody))
		//handle issue comment
		go handleIssueComment(hookNote)
	}
}

func (c *HookEventControllers) handlePullReq() {

}

func (c *HookEventControllers) handlePushTag() {

}

func (c *HookEventControllers) handleIssue() {
	logs.Info(string(c.Ctx.Input.RequestBody))
	issueHook := models.IssuePayload{}
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &issueHook)
	if err != nil {
		logs.Error(err, "\n, RequestBody: ", string(c.Ctx.Input.RequestBody))
		return
	}
	cuAccount := issueHook.Sender.Login
	if issueHook.Issue.Number == "" || cuAccount == "" {
		logs.Error("Data has null values: issueNum, cuAccount: ", issueHook.Issue.Number, cuAccount)
		return
	}
	nameSpace := util.TrimString(issueHook.Repository.NameSpace)
	organizationID := int8(1)
	organizationID = taskhandler.GetOrganizationId(nameSpace)
	botCuAccountStr := beego.AppConfig.String("cve::bot_cu_account")
	botCuAccountList := strings.Split(botCuAccountStr, ",")
	if len(botCuAccountList) > 0 {
		for _, botCu := range botCuAccountList {
			if cuAccount == botCu {
				logs.Error(cuAccount, ", Ignore this comment")
				return
			}
		}
	}
	hookPwd := beego.AppConfig.String("hook::hookpwd")
	issueHook.Password = util.TrimString(issueHook.Password)
	if issueHook.Password != hookPwd {
		logs.Error("Hook callback pwd verification error, hook: ", issueHook)
		return
	}
	if issueHook.Action == "assign" {
		//Update the person in charge of the issue template
		issueTmp := models.IssueTemplate{IssueNum: issueHook.Iid, IssueId: issueHook.Issue.Id}
		err := models.GetIssueTemplateByColName(&issueTmp, "issue_num", "issue_id")
		if err != nil {
			logs.Error(err, ",issueTmp: ", issueTmp)
			return
		}
		issueTmp.Assignee = issueHook.Assignee.Login
		err = models.UpdateIssueTemplate(&issueTmp, "issue_assignee")
		if err != nil {
			logs.Error(err, ",issueTmp: ", issueTmp)
		}
	}
	if issueHook.Action == "state_change" {
		//handle issue state change
		err = handleIssueStateChange(&issueHook)
		if err != nil {
			logs.Error(err, "\n,", issueHook)
			return
		}
	}
	if issueHook.Action == "open" {
		owner, token := common.GetOwnerAndToken(organizationID)
		issueTmp := models.IssueTemplate{IssueNum: issueHook.Iid, IssueId: issueHook.Issue.Id}
		err := models.GetIssueTemplateByColName(&issueTmp, "issue_num", "issue_id")
		if err == nil && issueTmp.TemplateId > 0 {
			vc := models.VulnCenter{CveId: issueTmp.CveId}
			vcErr := models.GetVulnCenterByCid(&vc, "CveId")
			if vcErr == nil && vc.CveId > 0 && vc.OrganizationID == organizationID {
				//cc := fmt.Sprintf(CommentRepeatIssue, "@"+cuAccount, issueTmp.CveNum, issueTmp.IssueNum)
				//taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, issueTmp.Repo, token)
				logs.Error("Duplicate webhook data is discarded directly, cveNum:", vc.CveNum, ",packName: ", vc.RepoName)
				return
			}
		}
		err = gitAddIssueProc(&issueHook, organizationID)
		if err != nil {
			logs.Error(err)
		}
		issueTmp = models.IssueTemplate{IssueNum: issueHook.Iid, IssueId: issueHook.Issue.Id}
		err = models.GetIssueTemplateByColName(&issueTmp, "issue_num", "issue_id")
		if err == nil {
			PostTriggerGetCve(issueTmp, owner, token, cuAccount)
		}
		return
	}
	if issueHook.Action == "delete" {
		err = gitDelIssueProc(&issueHook, organizationID)
		if err != nil {
			logs.Error(err, "\n, ", issueHook)
			return
		}
	}
}

func closeIssuePrivilage(issueHook *models.IssuePayload, issueTmp *models.IssueTemplate,
	token, owner, fixed, unFix string, cveCenter *models.VulnCenter) bool {
	closePrBool := true
	if issueHook.Sender.UserName != "" && len(issueHook.Sender.UserName) > 1 {
		if isReviewer(util.TrimString(issueHook.Sender.UserName)) {
			if msg, tb, ok := checkIssueClosedAnalysisComplete(issueTmp); !ok {
				//send comment to issue
				issueTmp.IssueStatus = 1
				issueTmp.MtAuditFlag = 1
				issueTmp.IssueLabel = unFix
				issueTmp.StatusName = "open"
				_, issueErr := taskhandler.UpdateIssueToGit(token, owner, issueTmp.Repo,
					*cveCenter, *issueTmp)
				if issueErr == nil {
					na := "\n**请确认分析内容的准确性,待分析内容请填写完整,否则将无法关闭当前issue.**"
					cc := fmt.Sprintf(ContentReview, "@"+issueHook.Sender.UserName) + tb + na
					taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, issueTmp.Repo, token)
					content := fmt.Sprintf("%v 仓库的CVE和安全问题的ISSUE,CVE编号: %v,", issueTmp.Repo, issueTmp.CveNum)
					taskhandler.SendPrivateLetters(token, content+msg, issueHook.Issue.Assignee.Login)
				}
			} else {
				issueTmp.StatusName = issueHook.Issue.StateName
				issueTmp.SaAuditFlag = 1
				issueTmp.MtAuditFlag = 1
				issueTmp.OpAuditFlag = 1
				issueTmp.Status = 3
				if isNormalCloseIssue(issueTmp.CveId, issueTmp.IssueStatus) {
					issueTmp.IssueStatus = 2
					cveCenter.IsExport = 3
					issueTmp.IssueLabel = fixed
				} else {
					issueTmp.IssueStatus = 6
					cveCenter.IsExport = 2
					issueTmp.IssueLabel = unFix
				}
			}
			closePrBool = false
		}
	}
	return closePrBool
}

func sigReviewSend(issueHook *models.IssuePayload, issueTmp *models.IssueTemplate,
	token, owner, fixed, unFix, assignee string, cveCenter *models.VulnCenter) {
	issueTmp.IssueStatus = 1
	issueTmp.Status = 1
	issueTmp.IssueLabel = unFix
	issueTmp.StatusName = "open"
	_, issueErr := taskhandler.UpdateIssueToGit(token, owner, issueTmp.Repo,
		*cveCenter, *issueTmp)
	if issueErr == nil {
		if issueTmp.OpAuditFlag == 2 {
			cc := fmt.Sprintf(IssueErroFormat, assignee)
			taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, issueTmp.Repo, token)
			content := fmt.Sprintf(CommentPrivateOpenEuler, issueTmp.Repo, issueTmp.CveNum)
			taskhandler.SendPrivateLetters(token, content, issueHook.Sender.UserName)
		} else if issueTmp.OpAuditFlag == 0 {
			list, revErr := models.GetSecurityReviewerList()
			if revErr == nil && len(list) > 0 {
				content := fmt.Sprintf(CommentPrivateReview, issueTmp.Repo, issueTmp.CveNum)
				ns := make([]string, len(list))
				for k, v := range list {
					ns[k] = "@" + v.NameSpace + " "
					taskhandler.SendPrivateLetters(token, content, v.NameSpace)
				}
				if len(ns) > 0 {
					cc := fmt.Sprintf(CommentReviewRemind, strings.Join(ns, ","))
					taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, issueTmp.Repo, token)
				}
			} else {
				logs.Error("revErr: ", revErr)
			}
		}
	}
}

func getMaintainer(path, prSender, assignee string) string {
	maintainerList, mainOk := models.QueryRepoAllMaintainer(path)
	assList := []string{}
	if mainOk && len(maintainerList) > 0 {
		for _, v := range maintainerList {
			assList = append(assList, "@"+v.MemberName+" ")
		}
	}
	if prSender != "" && len(prSender) > 1 {
		isListBool := common.IsValueInList("@"+prSender+" ", assList)
		if !isListBool {
			assList = append(assList, "@"+prSender+" ")
		}
	}
	maintainerVaule := ""
	if len(assList) > 0 {
		maintainerVaule = strings.Join(assList, ",")
	} else {
		maintainerVaule = "@" + assignee + " "
	}
	return maintainerVaule
}

func otherCloseIssueProc(issueHook *models.IssuePayload, issueTmp *models.IssueTemplate,
	token, owner, fixed, unFix, path string, cveCenter *models.VulnCenter) {
	unFixList := taskhandler.CheckAffectVerComplete(issueTmp.AffectedVersion, issueTmp.Repo,
		issueTmp.OwnedVersion, cveCenter.OrganizationID)
	if len(unFixList) > 0 {
		//send comment to issue
		issueTmp.IssueStatus = 1
		issueTmp.IssueLabel = unFix
		issueTmp.StatusName = "open"
		_, issueErr := taskhandler.UpdateIssueToGit(token, owner, issueTmp.Repo,
			*cveCenter, *issueTmp)
		if issueErr == nil {
			na := "\n**请确认分支信息是否填写完整,否则将无法关闭当前issue.**"
			cc := fmt.Sprintf(CommentCheckVersion, issueHook.Sender.UserName, strings.Join(unFixList, ",")) + na
			taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, issueTmp.Repo, token)
			content := fmt.Sprintf("%v 仓库的CVE和安全问题的ISSUE,CVE编号: %v,", issueTmp.Repo, issueTmp.CveNum)
			taskhandler.SendPrivateLetters(token, content, issueHook.Sender.UserName)
		}
	} else {
		commonFunc := checkGaussIssueClosedAnalysisComplete
		if cveCenter.OrganizationID == 4 {
			commonFunc = checkLooKengIssueClosedAnalysisComplete
		} else if cveCenter.OrganizationID == 3 {
			commonFunc = checkSporeIssueClosedAnalysisComplete
		}
		if _, tb, ok := commonFunc(issueTmp); !ok {
			//send comment to issue
			issueTmp.IssueStatus = 1
			issueTmp.IssueLabel = unFix
			issueTmp.StatusName = "open"
			_, issueErr := taskhandler.UpdateIssueToGit(token, owner, path,
				*cveCenter, *issueTmp)
			if issueErr == nil {
				na := "\n**请确认分析内容的准确性,待分析内容请填写完整,否则将无法关闭当前issue.**"
				cc := fmt.Sprintf(ContentReview, "@"+issueHook.Sender.UserName) + tb + na
				taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, path, token)
			}
		} else {
			issueTmp.IssueLabel = unFix
			issueTmp.StatusName = "open"
			issueTmp.Status = 1
			assignee := "@" + issueTmp.Assignee
			issuePrFlag := VerifyIssueAsPr(issueTmp, *cveCenter, false,
				assignee, issueHook.Sender.UserName)
			if issuePrFlag {
				//1. change issue status
				issueTmp.IssueStatus = 2
				cveCenter.IsExport = 3
				issueTmp.StatusName = issueHook.Issue.StateName
				issueTmp.Status = 3
				if isNormalCloseIssue(issueTmp.CveId, issueTmp.IssueStatus) {
					issueTmp.IssueStatus = 2
					cveCenter.IsExport = 3
					issueTmp.IssueLabel = fixed
				} else {
					issueTmp.IssueStatus = 6
					cveCenter.IsExport = 2
					issueTmp.IssueLabel = unFix
				}
			} else {
				issueTmp.IssueStatus = 1
				cveCenter.IsExport = 0
			}
		}
	}
}

func closeIssueProc(issueHook *models.IssuePayload, issueTmp *models.IssueTemplate,
	token, owner, fixed, unFix string, cveCenter *models.VulnCenter) {
	closePrBool := true
	closeIssuePrFlag, closeOk := beego.AppConfig.Int64("cve::close_issue_privilege")
	if closeOk == nil && closeIssuePrFlag == 1 {
		closePrBool = closeIssuePrivilage(issueHook, issueTmp,
			token, owner, fixed, unFix, cveCenter)
	}
	if closePrBool {
		issueTmp.Status = 1
		cveCenter.IsExport = 0
		issueTmp.MtAuditFlag = 1
		assignee := getMaintainer(issueTmp.Repo, issueHook.Sender.UserName, issueTmp.Assignee)
		openScoreFlag := true
		if issueTmp.OpenEulerScore != issueTmp.NVDScore && issueTmp.NVDScore > 0 &&
			issueTmp.OpAuditFlag != 1 && issueTmp.OpenEulerScore > 0 {
			//send comment to issue
			openScoreFlag = false
			sigReviewSend(issueHook, issueTmp, token, owner, fixed, unFix, assignee, cveCenter)
		}
		if openScoreFlag {
			unFixList := taskhandler.CheckAffectVerComplete(issueTmp.AffectedVersion, issueTmp.Repo,
				issueTmp.OwnedVersion, cveCenter.OrganizationID)
			if len(unFixList) > 0 {
				//send comment to issue
				issueTmp.IssueStatus = 1
				issueTmp.IssueLabel = unFix
				issueTmp.StatusName = "open"
				_, issueErr := taskhandler.UpdateIssueToGit(token, owner, issueTmp.Repo,
					*cveCenter, *issueTmp)
				if issueErr == nil {
					na := "\n**请确认分支信息是否填写完整,否则将无法关闭当前issue.**"
					cc := fmt.Sprintf(CommentCheckVersion, issueHook.Sender.UserName, strings.Join(unFixList, ",")) + na
					taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, issueTmp.Repo, token)
					content := fmt.Sprintf("%v 仓库的CVE和安全问题的ISSUE,CVE编号: %v,", issueTmp.Repo, issueTmp.CveNum)
					taskhandler.SendPrivateLetters(token, content, issueHook.Sender.UserName)
				}
			} else {
				if msg, tb, ok := checkIssueClosedAnalysisComplete(issueTmp); !ok {
					//send comment to issue
					issueTmp.IssueStatus = 1
					issueTmp.IssueLabel = unFix
					issueTmp.StatusName = "open"
					_, issueErr := taskhandler.UpdateIssueToGit(token, owner, issueTmp.Repo,
						*cveCenter, *issueTmp)
					if issueErr == nil {
						na := "\n**请确认分析内容的准确性,待分析内容请填写完整,否则将无法关闭当前issue.**"
						cc := fmt.Sprintf(ContentReview, "@"+issueHook.Sender.UserName) + tb + na
						taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, issueTmp.Repo, token)
						content := fmt.Sprintf("%v 仓库的CVE和安全问题的ISSUE,CVE编号: %v,", issueTmp.Repo, issueTmp.CveNum)
						taskhandler.SendPrivateLetters(token, content+msg, issueHook.Sender.UserName)
					}
				} else {
					//1. change issue status
					issueTmp.IssueStatus = 2
					//issueTmp.Status = 3
					cveCenter.IsExport = 3
					if issueTmp.MtAuditFlag == 0 {
						issueTmp.IssueStatus = 1
						issueTmp.Status = 1
						cveCenter.IsExport = 0
						issueTmp.IssueLabel = unFix
						issueTmp.StatusName = "open"
						_, issueErr := taskhandler.UpdateIssueToGit(token, owner, issueTmp.Repo,
							*cveCenter, *issueTmp)
						if issueErr == nil {
							na := "\n**issue关闭前,请确认模板分析内容的准确性与完整性,确认无误后,请在评论区输入: /approve, 否则无法关闭当前issue.**"
							cc := fmt.Sprintf(ContentReview, assignee) + tb + na
							taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, issueTmp.Repo, token)
						}
						return
					}
					issueTmp.IssueLabel = unFix
					issueTmp.StatusName = "open"
					issueTmp.Status = 1
					issuePrFlag := VerifyIssueAsPr(issueTmp, *cveCenter, false,
						assignee, issueHook.Sender.UserName)
					if issuePrFlag {
						issueTmp.StatusName = issueHook.Issue.StateName
						issueTmp.Status = 3
						if isNormalCloseIssue(issueTmp.CveId, issueTmp.IssueStatus) {
							issueTmp.IssueStatus = 2
							cveCenter.IsExport = 3
							issueTmp.IssueLabel = fixed
						} else {
							issueTmp.IssueStatus = 6
							cveCenter.IsExport = 2
							issueTmp.IssueLabel = unFix
						}
					} else {
						issueTmp.IssueStatus = 1
						cveCenter.IsExport = 0
					}
				}
			}
		}
	}
}

// Entry function for handling issue status
func handleIssueStateChange(issueHook *models.IssuePayload) error {
	unFix := beego.AppConfig.String("labelUnFix")
	fixed := beego.AppConfig.String("labelFixed")
	uNaffected := beego.AppConfig.String("labeUnaffected")
	issueId := issueHook.Issue.Id
	issueTmp := models.IssueTemplate{}
	issueTmp.IssueId = issueId
	issueTmp.IssueNum = issueHook.Iid
	repoPath := ""
	if issueHook.Issue.Repository.Path != "" &&
		len(issueHook.Issue.Repository.Path) > 1 {
		repoPath = issueHook.Issue.Repository.Path
	}
	issueErr := models.GetIssueTemplateByColName(&issueTmp, "issue_num", "issue_id")
	if issueErr != nil {
		return issueErr
	}
	path := issueTmp.Repo
	cveCenter := models.VulnCenter{CveId: issueTmp.CveId, CveNum: issueTmp.CveNum}
	cveErr := models.GetVulnCenterByCid(&cveCenter, "cve_id", "cve_num")
	if cveErr != nil {
		return cveErr
	}
	if len(repoPath) > 1 && repoPath != path {
		cveCenter.PackName = repoPath
		cveCenter.RepoName = issueTmp.OwnedComponent
		models.UpdateVulnCenter(&cveCenter, "PackName", "RepoName")
		issueTmp.Repo = repoPath
		models.UpdateIssueTemplate(&issueTmp, "Repo")
		path = repoPath
	}
	if issueHook.Issue.StateName == "已挂起" {
		logs.Error("The current issue has been suspended and will not be processed, issueHook: ", issueHook)
		issueTmp.Status = 5
		models.UpdateIssueTemplate(&issueTmp, "Status")
		return errors.New("The current issue has been suspended and will not be processed")
	}
	if issueHook.Issue.StateName == "已拒绝" {
		logs.Error("The current issue has been rejected and will not be processed, issueHook: ", issueHook)
		issueTmp.Status = 4
		models.UpdateIssueTemplate(&issueTmp, "Status")
		return errors.New("The current issue has been rejected and will not be processed")
	}
	owner, token := common.GetOwnerAndToken(cveCenter.OrganizationID)
	issueTmp.StatusName = issueHook.Issue.StateName
	logs.Info("Initiating issue status modification, sponsor: @", issueHook.Sender.UserName, ", Modify status: ",
		issueHook.Issue.StateName, ", data: ", issueHook)
	switch issueHook.State {
	case IssueOpenState:
		issueTmp.Status = 1
		cveCenter.IsExport = 0
		checkFunc := checkIssueAnalysisComplete
		if cveCenter.OrganizationID == 2 {
			checkFunc = checkGaussIssueAnalysisComplete
		} else if cveCenter.OrganizationID == 3 {
			checkFunc = checkSporeIssueAnalysisComplete
		} else if cveCenter.OrganizationID == 4 {
			checkFunc = checkLooKengIssueAnalysisComplete
		}
		_, _, ok := checkFunc(&issueTmp)
		if ok {
			issueTmp.IssueStatus = 3
		} else {
			issueTmp.IssueStatus = 1
		}
		issueTmp.IssueLabel = unFix
		//issueTmp.IssueStatus = 1
	case IssueProgressState:
		issueTmp.Status = 2
		cveCenter.IsExport = 0
		checkFunc := checkIssueAnalysisComplete
		if cveCenter.OrganizationID == 2 {
			checkFunc = checkGaussIssueAnalysisComplete
		} else if cveCenter.OrganizationID == 3 {
			checkFunc = checkSporeIssueAnalysisComplete
		} else if cveCenter.OrganizationID == 4 {
			checkFunc = checkLooKengIssueAnalysisComplete
		}
		_, _, ok := checkFunc(&issueTmp)
		if ok {
			issueTmp.IssueStatus = 3
		} else {
			issueTmp.IssueStatus = 1
		}
		issueTmp.IssueLabel = unFix
	case IssueCloseState:
		if issueTmp.Status == 3 {
			// The issue has been closed and cannot be operated again
			logs.Error("The issue has been closed and cannot be operated again,issuetmp: ", issueTmp)
			return errors.New("The issue has been closed and cannot be operated again")
		}
		if cveCenter.OrganizationID == 1 {
			closeIssueProc(issueHook, &issueTmp, token, owner, fixed, unFix, &cveCenter)
		} else {
			otherCloseIssueProc(issueHook, &issueTmp, token, owner, fixed, unFix, path, &cveCenter)
		}
	case IssueRejectState:
		issueTmp.Status = 4
		issueTmp.IssueStatus = 6
		cveCenter.IsExport = 2
		issueTmp.IssueLabel = uNaffected
	}
	updateBool := updateTempAndCenter(issueTmp, cveCenter, token, owner)
	if !updateBool {
		return errors.New("handle issue state hook appear error maybe some step fail")
	}
	return nil
}

// When the issue status is complete, verify whether the pr is associated
func VerifyIssueAsPr(issueTmp *models.IssueTemplate, cveCenter models.VulnCenter,
	effectFlag bool, assignee, prSend string) bool {
	sn := models.SecurityNotice{CveId: issueTmp.CveId, CveNum: issueTmp.CveNum}
	secErr := sn.Read("cve_id", "cve_num")
	if secErr != nil {
		logs.Error("no data has been found, issueTmp: ", issueTmp)
		return true
	}
	affectBranchsxList := make([]string, 0)
	affectedBranchs := ""
	path := cveCenter.PackName
	affectProductList := make([]string, 0)
	tmpAffectBranchsxList := make([]string, 0)
	owner, token := common.GetOwnerAndToken(cveCenter.OrganizationID)
	if cveCenter.OrganizationID == 4 {
		affectedBranchs = beego.AppConfig.String("openlookeng::openlookeng_version")
		affectBranchsxList = taskhandler.CreateBrandAndTags(token, owner, path, cveCenter.OrganizationID)
	} else if cveCenter.OrganizationID == 3 {
		affectedBranchs = beego.AppConfig.String("mindspore::mindspore_version")
		affectBranchsxList = taskhandler.CreateBrandAndTags(token, owner, path, cveCenter.OrganizationID)
	} else if cveCenter.OrganizationID == 2 {
		affectedBranchs = strings.ReplaceAll(sn.AffectProduct, "/", ",")
		if len(path) < 2 {
			path = beego.AppConfig.String("opengauss::gauss_issue_path")
		}
		affectBranchsxList, _ = taskhandler.GetBranchesInfo(token, owner, path, cveCenter.OrganizationID)
	} else {
		affectedBranchs = beego.AppConfig.String("cve::affected_branchs")
		path = issueTmp.Repo
		if affectedBranchs != "" && len(affectedBranchs) > 0 {
			affectBranchsxList = strings.Split(affectedBranchs, ",")
		}
	}

	if sn.AffectProduct != "" && len(sn.AffectProduct) > 1 {
		tmpAffectBranchsxList = strings.Split(sn.AffectProduct, "/")
	}
	affectProductList = common.RemoveDupString(tmpAffectBranchsxList)
	if len(affectProductList) > 0 {
		issueTmp.SaAuditFlag = 0
		branchMaps := make(map[string]bool)
		for _, brands := range affectProductList {
			brands = common.BranchVersionRep(brands)
			if len(affectBranchsxList) > 0 {
				keyBandList := []string{}
				for _, affectBranch := range affectBranchsxList {
					affectBranch = common.BranchVersionRep(affectBranch)
					if affectBranch == brands {
						// Query the repo that needs to submit an issue
						if cveCenter.OrganizationID == 3 {
							mdbt := models.MindSporeBrandTags{PackageName: path, Tags: affectBranch}
							mtErr := models.QueryMindSporeBrandTags(&mdbt, "PackageName", "Tags")
							if mtErr == nil {
								keyBandList = append(keyBandList, mdbt.Brand)
							}
						} else if cveCenter.OrganizationID == 4 {
							keyBandList = append(keyBandList, "master")
						} else {
							keyBandList = append(keyBandList, affectBranch)
						}
					}
				}
				if len(keyBandList) > 0 {
					prList := getRepoIssueAllPR(keyBandList, token, owner, path, *issueTmp)
					for _, brh := range keyBandList {
						if len(prList) == 0 {
							branchMaps[brh] = false
						} else {
							for _, prl := range prList {
								if brh == prl.Branch {
									branchMaps[brh] = prl.BrFlag
									break
								}
							}
						}
						if _, ok := branchMaps[brh]; !ok {
							branchMaps[brh] = false
						}
					}
				}
			}
		}
		if len(branchMaps) == 0 {
			logs.Info("sn.AffectProduct: ", sn.AffectProduct, ",There is no branch to follow to associate with pr")
			return true
		}
		brandStr := ""
		//logs.Info("branchMaps===> ", branchMaps)
		for brand, bv := range branchMaps {
			if !bv {
				logs.Error("brand: ", brand, ", pr is not related to issue, issueTmp: ", issueTmp)
				brandStr = brandStr + brand + "/"
			}
		}
		if brandStr != "" && len(brandStr) > 1 {
			_, issueErr := taskhandler.UpdateIssueToGit(token, owner, path,
				cveCenter, *issueTmp)
			if issueErr == nil {
				commentBody := assignee + "\n" +
					"关闭issue前,需要将受影响的分支在合并pr时关联上当前issue编号: #" + issueTmp.IssueNum + "\n" +
					"受影响分支: " + brandStr[:len(brandStr)-1] + "\n" +
					"具体操作参考: " + "https://gitee.com/help/articles/4142" + "\n"
				taskhandler.AddCommentToIssue(commentBody, issueTmp.IssueNum, owner, path, token)
				content := issueTmp.Repo + " 仓库的CVE和安全问题的ISSUE,CVE编号: " + issueTmp.CveNum +
					",关闭issue前,需要将受影响的分支在合并pr时关联上当前issue编号: #" + issueTmp.IssueNum +
					",受影响分支: " + brandStr[:len(brandStr)-1] +
					",具体操作参考: " + "https://gitee.com/help/articles/4142."
				taskhandler.SendPrivateLetters(token, content, prSend)
			}
			return false
		}
	} else {
		if effectFlag && issueTmp.SaAuditFlag == 0 {
			unaffectedBranchList := []string{}
			if issueTmp.AffectedVersion != "" && len(issueTmp.AffectedVersion) > 1 {
				unaffectedBranchList = paraAffectBrands(issueTmp.AffectedVersion)
			}
			branchStrs := ""
			if len(unaffectedBranchList) > 0 {
				for _, brands := range unaffectedBranchList {
					if len(affectBranchsxList) > 0 {
						for _, affectBranch := range affectBranchsxList {
							if affectBranch == brands {
								branchStrs = branchStrs + brands + "/"
							}
						}
					}
				}
			}
			if branchStrs != "" && len(branchStrs) > 1 {
				branchStrs = branchStrs[:len(branchStrs)-1]
				list, err := models.GetSecurityReviewerList()
				if err != nil {
					logs.Error("err: ", err, "\n, issueTmp: ", issueTmp)
					issueTmp.SaAuditFlag = 1
					return true
				}
				if len(list) == 0 {
					logs.Error("list is null, issueTemp: ", issueTmp)
					issueTmp.SaAuditFlag = 1
					return true
				}
				anName := []string{}
				content := fmt.Sprintf(CommentPrivateReview, issueTmp.Repo, issueTmp.CveNum)
				for _, v := range list {
					anName = append(anName, "@"+v.NameSpace+" ")
					taskhandler.SendPrivateLetters(token, content, v.NameSpace)
				}
				if len(anName) > 0 {
					_, issueErr := taskhandler.UpdateIssueToGit(token, owner, issueTmp.Repo,
						cveCenter, *issueTmp)
					if issueErr == nil {
						assignee := strings.Join(anName, ",")
						commentBody := assignee + "\n" +
							"关闭issue前,请确认分支: " + branchStrs + ": 受影响/不受影响, 如受影响,请联系maintainer: @" +
							issueTmp.Assignee + ", **进行处理后, 或者按照模板格式在评论区填写内容, 最后记得在评论区回复: /approve ,才能正常关闭issue.**"
						taskhandler.AddCommentToIssue(commentBody, issueTmp.IssueNum, owner, issueTmp.Repo, token)
					}
					return false
				} else {
					issueTmp.SaAuditFlag = 1
				}
			} else {
				issueTmp.SaAuditFlag = 1
			}
		}
	}
	return true
}

func paraAffectBrands(affectedVersion string) (unaffectedBranchList []string) {
	brandsGroup := strings.Split(affectedVersion, ",")
	if len(brandsGroup) > 0 {
		for _, brand := range brandsGroup {
			if brand == "" || len(brand) < 2 {
				continue
			}
			brand = common.BranchVersionRep(brand)
			brandList := strings.Split(brand, ":")
			if len(brandList) > 1 {
				prams := strings.Replace(brandList[1], " ", "", -1)
				if prams != "受影响" {
					unaffectedBranchList = append(unaffectedBranchList, brandList[0])
				}
			} else {
				brandList = strings.Split(brand, "：")
				if len(brandList) > 1 {
					prams := strings.Replace(brandList[1], " ", "", -1)
					if prams != "受影响" {
						unaffectedBranchList = append(unaffectedBranchList, brandList[0])
					}
				}
			}
			if len(brandList) == 1 {
				unaffectedBranchList = append(unaffectedBranchList, brandList[0])
			}
		}
	}
	return unaffectedBranchList
}

func paraAffectBrandBool(affectedVersion string) bool {
	unaffectedBranchList := make([]string, 0)
	brandsGroup := strings.Split(affectedVersion, ",")
	if len(brandsGroup) > 0 {
		for _, brand := range brandsGroup {
			if brand == "" || len(brand) < 2 {
				continue
			}
			brand = common.BranchVersionRep(brand)
			brandList := strings.Split(brand, ":")
			if len(brandList) > 1 {
				prams := strings.Replace(brandList[1], " ", "", -1)
				if prams == "受影响" || prams == "不受影响" {
					unaffectedBranchList = append(unaffectedBranchList, brandList[0])
				}
			} else {
				brandList = strings.Split(brand, "：")
				if len(brandList) > 1 {
					prams := strings.Replace(brandList[1], " ", "", -1)
					if prams == "受影响" || prams == "不受影响" {
						unaffectedBranchList = append(unaffectedBranchList, brandList[0])
					}
				}
			}
		}
	}
	if len(unaffectedBranchList) > 0 {
		return true
	}
	return false
}

func getPRRelatedBrandsAllIssue(token, owner, repo string, num int, issueNum string) bool {
	issueFlag := false
	url := fmt.Sprintf(`https://gitee.com/api/v5/repos/%s/%s/pulls/%v/issues`, owner, repo, num)
	pageSize := 20
	pageCount := 1
	req, err := http.NewRequest(http.MethodGet, url, nil)
	if err != nil {
		logs.Error(err)
		return false
	}
	q := req.URL.Query()
	q.Add("access_token", token)
	q.Add("per_page", strconv.Itoa(pageSize))
	for {
		q.Del("page")
		q.Add("page", strconv.Itoa(pageCount))
		req.URL.RawQuery = q.Encode()
		resp, err := http.DefaultClient.Do(req)
		if err != nil {
			logs.Error(err)
			break
		}
		if resp.StatusCode == http.StatusOK {
			var il []models.HookIssue
			read, err := ioutil.ReadAll(resp.Body)
			resp.Body.Close()
			if err != nil {
				logs.Error(err)
				break
			}
			err = json.Unmarshal(read, &il)
			if err != nil {
				logs.Error(err)
				break
			}
			for _, v := range il {
				d, ok := isLegallyIssue(v)
				if ok {
					if issueNum == d.Number {
						issueFlag = true
						break
					}
				}
			}
			if len(il) < pageSize {
				break
			}
			pageCount++
		} else {
			resp.Body.Close()
			break
		}
	}
	return issueFlag
}

// Verify that the current issue meets the requirements
func isLegallyIssue(i models.HookIssue) (pri models.PullRequestIssue, ok bool) {
	if i.IssueType != CIssueType || (i.State != "closed" && i.State != "已完成") {
		return
	}
	tt := strings.Trim(i.Title, " ")
	regCveNum := regexp.MustCompile(`(?mi)CVE-[\d]{1,}-([\d]{1,})$`)
	sm := util.RegexpCveNumber.FindAllStringSubmatch(i.Body, -1)
	if len(sm) > 0 && len(sm[0]) > 0 {
		val := sm[0][1]
		tt = util.GetCveNumber(util.TrimString(val))
		if tt != "" && regCveNum.Match([]byte(tt)) {
			ok = true
		}
	}
	if ok {
		pri.Id = i.Id
		pri.Number = i.Number
		pri.CveNumber = tt
		pri.Repo = i.Repository.Path
	}
	return
}

// Get the pr associated with a single repo
func getRepoIssueAllPR(affectBranch []string, token, owner, repo string, isTemp models.IssueTemplate) (prList []models.PullRequestIssue) {
	url := fmt.Sprintf("https://gitee.com/api/v5/repos/%v/issues/%v/pull_requests", owner, isTemp.IssueNum)
	req, err := http.NewRequest(http.MethodGet, url, nil)
	if err != nil {
		logs.Error("NewRequest, url: ", url, ",err: ", err)
		return
	}
	q := req.URL.Query()
	q.Add("access_token", token)
	q.Add("repo", repo)
	req.URL.RawQuery = q.Encode()
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		logs.Error("DefaultClient, url: ", url, ",err: ", err)
		return
	}
	if resp.StatusCode == http.StatusOK {
		issuePr := make([]map[string]interface{}, 0)
		read, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			logs.Error("ReadAll, url: ", url, ",err: ", err)
			return
		}
		resp.Body.Close()
		//logs.Info("getRepoIssueAllPR, body ===> ", read)
		err = json.Unmarshal(read, &issuePr)
		if err != nil {
			logs.Error("Unmarshal, url: ", url, ",err: ", err)
			return
		}
		logs.Info("issuePr: ", issuePr)
		for _, brh := range affectBranch {
			pr := models.PullRequestIssue{}
			pr.Branch = brh
			pr.BrFlag = false
			for _, v := range issuePr {
				if _, ok := v["id"]; !ok {
					continue
				}
				if v["state"].(string) == "merged" && v["mergeable"].(bool) {
					if v["base"].(map[string]interface{})["label"].(string) == brh {
						pr.Id = int64(v["id"].(float64))
						pr.Number = isTemp.IssueNum
						pr.CveNumber = isTemp.CveNum
						pr.Repo = repo
						pr.BrFlag = true
						break
					}
				}
			}
			prList = append(prList, pr)
		}
	} else {
		resp.Body.Close()
	}
	return
}

func isNormalCloseIssue(cveID int64, issueState int8) bool {
	if issueState == 1 {
		return false
	}
	score, err := models.QueryIssueScore(cveID)
	if err != nil {
		logs.Error("err: ", err, "\n, cveID: ", cveID)
		return false
	}
	if score.Ostatus != 3 {
		return false
	}
	return true
}

// update data
func updateTempAndCenter(issueTmp models.IssueTemplate, cveCenter models.VulnCenter, token, owner string) bool {
	appearErr := 0
	affectBrandFlag := false
	uNaffected := beego.AppConfig.String("labeUnaffected")
	labelFixed := beego.AppConfig.String("labelFixed")
	labelUnFix := beego.AppConfig.String("labelUnFix")
	labeAbiChanged := beego.AppConfig.String("labeAbiChanged")
	path := cveCenter.PackName
	sn := models.SecurityNotice{CveId: issueTmp.CveId, CveNum: issueTmp.CveNum}
	snErr := sn.Read("cve_id", "cve_num")
	if snErr != nil {
		logs.Error("err: ", snErr)
	} else {
		if issueTmp.Status > 2 {
			affectBranchsxList := make([]string, 0)
			affectedBranchs := ""
			if cveCenter.OrganizationID == 4 {
				affectedBranchs = strings.ReplaceAll(sn.AffectProduct, "/", ",")
			} else if cveCenter.OrganizationID == 3 {
				if sn.AffectProduct != "" && len(sn.AffectProduct) > 1 {
					tmpTagList := make([]string, 0)
					affectProductSlice := strings.Split(sn.AffectProduct, "/")
					for _, tags := range affectProductSlice {
						mdbt := models.MindSporeBrandTags{PackageName: path, Tags: tags}
						mtErr := models.QueryMindSporeBrandTags(&mdbt, "PackageName", "Tags")
						if mtErr == nil {
							tmpTagList = append(tmpTagList, mdbt.Brand)
						}
					}
					if len(tmpTagList) > 0 {
						sn.AffectProduct = strings.Join(tmpTagList, "/")
						affectedBranchs = strings.ReplaceAll(sn.AffectProduct, "/", ",")
					} else {
						sn.AffectProduct = ""
					}
				}
			} else if cveCenter.OrganizationID == 2 {
				affectedBranchs = strings.ReplaceAll(sn.AffectProduct, "/", ",")
			} else {
				affectedBranchs = beego.AppConfig.String("cve::affected_branchs")
			}
			if affectedBranchs != "" && len(affectedBranchs) > 0 {
				affectBranchsxList = strings.Split(affectedBranchs, ",")
			}
			if sn.AffectProduct != "" && len(sn.AffectProduct) > 1 {
				affectProductList := strings.Split(sn.AffectProduct, "/")
				if len(affectProductList) > 0 {
					for _, brands := range affectProductList {
						if len(affectBranchsxList) > 0 {
							for _, affectBranch := range affectBranchsxList {
								if affectBranch == brands {
									affectBrandFlag = true
									break
								}
							}
						}
						if affectBrandFlag {
							break
						}
					}
				}
			}
		}
		switch issueTmp.IssueStatus {
		case 2:
			sn.AffectStatus = "Fixed"
		case 6:
			sn.AffectStatus = "UnAffected"
		default:
			sn.AffectStatus = "UnFixed"
		}
		err := sn.Update("affect_status")
		if err != nil {
			appearErr++
			logs.Error("err: ", err, ", issueTmp.IssueStatus: ", issueTmp.IssueStatus)
		}
	}
	cveCenter.CveLevel = models.OpenEulerScoreProc(issueTmp.NVDScore)
	if len(cveCenter.CveVersion) > 0 && cveCenter.CveVersion[0] == ',' {
		cveCenter.CveVersion = cveCenter.CveVersion[1:]
	}
	update := models.UpdateVulnCenter(&cveCenter, "is_export", "cve_level", "CveVersion")
	if !update {
		logs.Error("update vulnCenter fail ")
		appearErr += 1
	}
	if issueTmp.StatusName == "closed" || issueTmp.Status == 3 {
		if affectBrandFlag {
			issueTmp.IssueLabel = labelFixed
		} else {
			issueTmp.IssueLabel = uNaffected
		}
	} else {
		issueTmp.IssueLabel = labelUnFix
	}

	labelSlice := make([]string, 0)
	labelSlice = taskhandler.AddLabelValue(token, path, issueTmp.IssueNum, owner, issueTmp.IssueLabel, 1)
	if len(labelSlice) > 0 {
		labelStr := strings.Join(labelSlice, ",")
		if issueTmp.Status == 3 {
			if affectBrandFlag {
				if strings.Contains(labelStr, uNaffected) {
					labelSlice = common.DeleteSliceValue(labelSlice, uNaffected)
				}
				if !strings.Contains(labelStr, labelFixed) {
					labelSlice = append(labelSlice, labelFixed)
				}
			} else {
				if strings.Contains(labelStr, labelFixed) {
					labelSlice = common.DeleteSliceValue(labelSlice, labelFixed)
				}
				if !strings.Contains(labelStr, uNaffected) {
					labelSlice = append(labelSlice, uNaffected)
				}
			}
			if strings.Contains(labelStr, labelUnFix) {
				labelSlice = common.DeleteSliceValue(labelSlice, labelUnFix)
			}
		} else {
			if !strings.Contains(labelStr, labelUnFix) {
				labelSlice = append(labelSlice, labelUnFix)
			}
		}
	} else {
		if issueTmp.Status == 3 {
			if affectBrandFlag {
				labelSlice = append(labelSlice, labelFixed)
			} else {
				labelSlice = append(labelSlice, uNaffected)
			}
		} else {
			labelSlice = append(labelSlice, labelUnFix)
		}
	}
	issueTmp.IssueLabel = strings.Join(labelSlice, ",")
	if issueTmp.Status == 3 && cveCenter.OrganizationID == 1 &&
		AbiAffectedVersionBool(issueTmp.AbiVersion) && !strings.Contains(issueTmp.IssueLabel, labeAbiChanged) {
		issueTmp.IssueLabel = issueTmp.IssueLabel + "," + labeAbiChanged
	}
	update = taskhandler.UpdateIssueLabels(token, path, issueTmp.IssueNum, owner, issueTmp.IssueLabel)
	if !update {
		logs.Error("update gitee issue label  fail ,", issueTmp.IssueNum, issueTmp.IssueLabel)
		appearErr++
	}
	issueTmp.CveLevel = models.OpenEulerScoreProc(issueTmp.OpenEulerScore)
	tpErr := models.UpdateIssueTemplate(&issueTmp, "status", "issue_status",
		"status_name", "issue_label", "mt_audit_flag", "sa_audit_flag", "cve_level")
	if tpErr != nil {
		logs.Error("tpErr: ", tpErr)
		appearErr += 1
	}
	if appearErr > 0 {
		logs.Error("handle issue state hook appear error maybe some step "+
			"fail, appearErr: ", appearErr, ",issuetmp: ", issueTmp)
		return false
	}
	return true
}

func AbiAffectedVersionBool(abiVersion string) bool {
	abiVersionList := []string{}
	brandsGroup := strings.Split(abiVersion, ",")
	if len(brandsGroup) > 0 {
		for _, brand := range brandsGroup {
			if brand == "" || len(brand) < 2 {
				continue
			}
			brand = common.BranchVersionRep(brand)
			brandList := strings.Split(brand, ":")
			if len(brandList) > 1 {
				prams := strings.Replace(brandList[1], " ", "", -1)
				if prams == "是" {
					abiVersionList = append(abiVersionList, brandList[0])
					break
				}
			} else {
				brandList = strings.Split(brand, "：")
				if len(brandList) > 1 {
					prams := strings.Replace(brandList[1], " ", "", -1)
					if prams == "是" {
						abiVersionList = append(abiVersionList, brandList[0])
						break
					}
				}
			}
		}
	}
	if len(abiVersionList) > 0 {
		return true
	}
	return false
}

func openEulerScoreReview(issueTmp *models.IssueTemplate, cuAccount, owner, token string) bool {
	approveFlag := true
	if isReviewer(cuAccount) {
		issueTmp.OpAuditFlag = 1
		approveFlag = false
		err := changeOpenEulerScoreStatus(issueTmp.CveId, 3)
		if err != nil {
			logs.Error("1.err: ", err, ",issueTmp: ", issueTmp)
		} else {
			err = models.UpdateIssueTemplate(issueTmp, "op_audit_flag")
			if err != nil {
				logs.Error("2.err: ", err, ",issueTmp: ", issueTmp)
			}
			taskhandler.AddCommentToIssue(fmt.Sprintf(ReviewApproveScore, issueTmp.Assignee, cuAccount),
				issueTmp.IssueNum, owner, issueTmp.Repo, token)
		}
	} else {
		taskhandler.AddCommentToIssue(fmt.Sprintf(CommentReviewRemindMaintainer, cuAccount),
			issueTmp.IssueNum, owner, issueTmp.Repo, token)
	}
	return approveFlag
}

func gaussMaintainerApprove(issueTmp *models.IssueTemplate, cuAccount, owner, token, fixed,
	unfixed, path string, cveCenter models.VulnCenter) {
	unFixList := taskhandler.CheckAffectVerComplete(issueTmp.AffectedVersion, issueTmp.Repo,
		issueTmp.OwnedVersion, cveCenter.OrganizationID)
	if len(unFixList) > 0 {
		na := "\n**请确认分支信息是否填写完整,否则将无法关闭当前issue.**"
		cc := fmt.Sprintf(CommentCheckVersion, cuAccount, strings.Join(unFixList, ",")) + na
		taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, path, token)
		return
	}
	if _, tb, ok := checkGaussIssueClosedAnalysisComplete(issueTmp); !ok {
		//send comment to issue
		na := "\n**请确认分析内容的准确性,待分析内容请填写完整,否则将无法关闭当前issue.**"
		cc := fmt.Sprintf(AnalysisComplete, cuAccount) + tb + na
		taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, path, token)
		return
	} else {
		if !isGaussReviewer(cuAccount) && issueTmp.Assignee != cuAccount {
			logs.Error("Invalid user review, cuAccount: ", cuAccount)
			taskhandler.AddCommentToIssue(fmt.Sprintf(`@%v maintainer具有通过(/approve或者/close)关闭issue, 否则请通过issue页面按钮关闭issue!`,
				cuAccount), issueTmp.IssueNum, owner, path, token)
			return
		}
		issueTmp.IssueLabel = unfixed
		issueTmp.StatusName = "open"
		issueTmp.Status = 1
		assignee := "@" + issueTmp.Assignee
		issuePrFlag := VerifyIssueAsPr(issueTmp, cveCenter, false,
			assignee, cuAccount)
		if issuePrFlag {
			issueTmp.IssueLabel = fixed
			issueTmp.StatusName = "closed"
			taskhandler.AddCommentToIssue(fmt.Sprintf(`@%v 你已审核模板内容, cve-manager 将关闭issue!`,
				cuAccount), issueTmp.IssueNum, owner, path, token)
			_, issueErr := taskhandler.UpdateIssueToGit(token, owner, issueTmp.Repo,
				cveCenter, *issueTmp)
			if issueErr == nil {
				logs.Info("Initiate an issue to close,issuetmp: ", issueTmp)
			} else {
				logs.Error("Issue closing operation failed, issuetmp: ", issueTmp, ",issueErr: ", issueErr)
				return
			}
			//issueTmp.SaAuditFlag = 1
			issueTmp.Status = 3
			if isNormalCloseIssue(issueTmp.CveId, issueTmp.IssueStatus) {
				issueTmp.IssueStatus = 2
				cveCenter.IsExport = 3
			} else {
				issueTmp.IssueStatus = 6
				cveCenter.IsExport = 2
			}
			gaussIssuePath := beego.AppConfig.String("opengauss::gauss_issue_path")
			issueTmp.Repo = gaussIssuePath
			updateBool := updateTempAndCenter(*issueTmp, cveCenter, token, owner)
			if !updateBool {
				return
			}
		}
	}
}

func looKengMaintainerApprove(issueTmp *models.IssueTemplate, cuAccount, owner, token, fixed,
	unfixed, path string, cveCenter models.VulnCenter) {
	unFixList := taskhandler.CheckAffectVerComplete(issueTmp.AffectedVersion, issueTmp.Repo,
		issueTmp.OwnedVersion, cveCenter.OrganizationID)
	if len(unFixList) > 0 {
		na := "\n**请确认分支信息是否填写完整,否则将无法关闭当前issue.**"
		cc := fmt.Sprintf(CommentCheckVersion, cuAccount, strings.Join(unFixList, ",")) + na
		taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, path, token)
		return
	}
	if _, tb, ok := checkLooKengIssueClosedAnalysisComplete(issueTmp); !ok {
		//send comment to issue
		na := "\n**请确认分析内容的准确性,待分析内容请填写完整,否则将无法关闭当前issue.**"
		cc := fmt.Sprintf(AnalysisComplete, cuAccount) + tb + na
		taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, path, token)
		return
	} else {
		if !isLooKengReviewer(cuAccount) && issueTmp.Assignee != cuAccount {
			logs.Error("Invalid user review, cuAccount: ", cuAccount)
			taskhandler.AddCommentToIssue(fmt.Sprintf(`@%v maintainer具有通过(/approve或者/close)关闭issue, 否则请通过issue页面按钮关闭issue!`,
				cuAccount), issueTmp.IssueNum, owner, path, token)
			return
		}
		issueTmp.IssueLabel = unfixed
		issueTmp.StatusName = "open"
		issueTmp.Status = 1
		assignee := "@" + issueTmp.Assignee
		issuePrFlag := VerifyIssueAsPr(issueTmp, cveCenter, false, assignee, cuAccount)
		if issuePrFlag {
			issueTmp.IssueLabel = fixed
			issueTmp.StatusName = "closed"
			taskhandler.AddCommentToIssue(fmt.Sprintf(`@%v 你已审核模板内容, cve-manager 将关闭issue!`,
				cuAccount), issueTmp.IssueNum, owner, path, token)
			_, issueErr := taskhandler.UpdateIssueToGit(token, owner, issueTmp.Repo,
				cveCenter, *issueTmp)
			if issueErr == nil {
				logs.Info("Initiate an issue to close,issuetmp: ", issueTmp)
			} else {
				logs.Error("Issue closing operation failed, issuetmp: ", issueTmp, ",issueErr: ", issueErr)
				return
			}
			//issueTmp.SaAuditFlag = 1
			issueTmp.Status = 3
			if isNormalCloseIssue(issueTmp.CveId, issueTmp.IssueStatus) {
				issueTmp.IssueStatus = 2
				cveCenter.IsExport = 3
			} else {
				issueTmp.IssueStatus = 6
				cveCenter.IsExport = 2
			}
			updateBool := updateTempAndCenter(*issueTmp, cveCenter, token, owner)
			if !updateBool {
				return
			}
		}
	}
}

func sporeMaintainerApprove(issueTmp *models.IssueTemplate, cuAccount, owner, token, fixed,
	unfixed, path string, cveCenter models.VulnCenter) {
	unFixList := taskhandler.CheckAffectVerComplete(issueTmp.AffectedVersion, issueTmp.Repo,
		issueTmp.OwnedVersion, cveCenter.OrganizationID)
	if len(unFixList) > 0 {
		na := "\n**请确认分支信息是否填写完整,否则将无法关闭当前issue.**"
		cc := fmt.Sprintf(CommentCheckVersion, cuAccount, strings.Join(unFixList, ",")) + na
		taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, path, token)
		return
	}
	if _, tb, ok := checkSporeIssueClosedAnalysisComplete(issueTmp); !ok {
		//send comment to issue
		na := "\n**请确认分析内容的准确性,待分析内容请填写完整,否则将无法关闭当前issue.**"
		cc := fmt.Sprintf(AnalysisComplete, cuAccount) + tb + na
		taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, path, token)
		return
	} else {
		if !isMindSporeReviewer(cuAccount) && issueTmp.Assignee != cuAccount {
			logs.Error("Invalid user review, cuAccount: ", cuAccount)
			taskhandler.AddCommentToIssue(fmt.Sprintf(`@%v maintainer具有通过(/approve或者/close)关闭issue, 否则请通过issue页面按钮关闭issue!`,
				cuAccount), issueTmp.IssueNum, owner, path, token)
			return
		}
		issueTmp.IssueLabel = unfixed
		issueTmp.StatusName = "open"
		issueTmp.Status = 1
		assignee := "@" + issueTmp.Assignee
		issuePrFlag := VerifyIssueAsPr(issueTmp, cveCenter, false, assignee, cuAccount)
		if issuePrFlag {
			issueTmp.IssueLabel = fixed
			issueTmp.StatusName = "closed"
			taskhandler.AddCommentToIssue(fmt.Sprintf(`@%v 你已审核模板内容, cve-manager 将关闭issue!`,
				cuAccount), issueTmp.IssueNum, owner, path, token)
			_, issueErr := taskhandler.UpdateIssueToGit(token, owner, issueTmp.Repo,
				cveCenter, *issueTmp)
			if issueErr == nil {
				logs.Info("Initiate an issue to close,issuetmp: ", issueTmp)
			} else {
				logs.Error("Issue closing operation failed, issuetmp: ", issueTmp, ",issueErr: ", issueErr)
				return
			}
			//issueTmp.SaAuditFlag = 1
			issueTmp.Status = 3
			if isNormalCloseIssue(issueTmp.CveId, issueTmp.IssueStatus) {
				issueTmp.IssueStatus = 2
				cveCenter.IsExport = 3
			} else {
				issueTmp.IssueStatus = 6
				cveCenter.IsExport = 2
			}
			updateBool := updateTempAndCenter(*issueTmp, cveCenter, token, owner)
			if !updateBool {
				return
			}
		}
	}
}

func maintainerApprove(issueTmp *models.IssueTemplate, cuAccount, owner, token, fixed,
	unfixed string, organizationID int8) {
	unFixList := taskhandler.CheckAffectVerComplete(issueTmp.AffectedVersion,
		issueTmp.Repo, issueTmp.OwnedVersion, organizationID)
	if len(unFixList) > 0 {
		na := "\n**请确认分支信息是否填写完整,否则将无法关闭当前issue.**"
		cc := fmt.Sprintf(CommentCheckVersion, cuAccount, strings.Join(unFixList, ",")) + na
		taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, issueTmp.Repo, token)
		return
	}
	if _, tb, ok := checkIssueClosedAnalysisComplete(issueTmp); !ok {
		//send comment to issue
		na := "\n**请确认分析内容的准确性,待分析内容请填写完整,否则将无法关闭当前issue.**"
		cc := fmt.Sprintf(AnalysisComplete, cuAccount) + tb + na
		taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, issueTmp.Repo, token)
		return
	} else {
		issueTmp.MtAuditFlag = 1
		err := models.UpdateIssueTemplate(issueTmp, "mt_audit_flag")
		if err != nil {
			logs.Error("upErr: ", err, "issueTmp: ", issueTmp)
			return
		}
		cveCenter := models.VulnCenter{CveId: issueTmp.CveId, CveNum: issueTmp.CveNum}
		err = models.GetVulnCenterByCid(&cveCenter, "cve_id", "cve_num")
		if err != nil {
			return
		}
		issueTmp.IssueLabel = unfixed
		issueTmp.StatusName = "open"
		assignee := getMaintainer(issueTmp.Repo, cuAccount, issueTmp.Assignee)
		issuePrFlag := VerifyIssueAsPr(issueTmp, cveCenter, false, assignee, cuAccount)
		if issuePrFlag {
			issueTmp.IssueLabel = fixed
			issueTmp.StatusName = "closed"
			taskhandler.AddCommentToIssue(fmt.Sprintf(`@%v 你已审核模板内容, cve-manager 将关闭issue!`,
				cuAccount), issueTmp.IssueNum, owner, issueTmp.Repo, token)
			_, issueErr := taskhandler.UpdateIssueToGit(token, owner, issueTmp.Repo,
				cveCenter, *issueTmp)
			if issueErr == nil {
				logs.Info("Initiate an issue to close, issuetmp: ", issueTmp)
			} else {
				logs.Error("Issue closing operation failed, issuetmp: ", issueTmp, ",issueErr: ", issueErr)
				return
			}
			//issueTmp.SaAuditFlag = 1
			issueTmp.Status = 3
			if isNormalCloseIssue(issueTmp.CveId, issueTmp.IssueStatus) {
				issueTmp.IssueStatus = 2
				cveCenter.IsExport = 3
			} else {
				issueTmp.IssueStatus = 6
				cveCenter.IsExport = 2
			}
			updateBool := updateTempAndCenter(*issueTmp, cveCenter, token, owner)
			if !updateBool {
				return
			}
		}
		return
	}
}

func securityApprove(issueTmp *models.IssueTemplate, cuAccount, owner, token,
	fixed, unfixed string, organizationID int8) {
	unFixList := taskhandler.CheckAffectVerComplete(issueTmp.AffectedVersion,
		issueTmp.Repo, issueTmp.OwnedVersion, organizationID)
	if len(unFixList) > 0 {
		na := "\n**请确认分支信息是否填写完整,否则将无法关闭当前issue.**"
		cc := fmt.Sprintf(CommentCheckVersion, cuAccount, strings.Join(unFixList, ",")) + na
		taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, issueTmp.Repo, token)
		return
	}
	if _, tb, ok := checkIssueClosedAnalysisComplete(issueTmp); !ok {
		//send comment to issue
		na := "\n**请确认分析内容的准确性,待分析内容请填写完整,否则将无法关闭当前issue.**"
		cc := fmt.Sprintf(AnalysisComplete, cuAccount) + tb + na
		taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, issueTmp.Repo, token)
		return
	} else {
		if !isReviewer(cuAccount) && issueTmp.Assignee != cuAccount {
			taskhandler.AddCommentToIssue(fmt.Sprintf(`@%v maintainer具有通过(/approve或者/close)关闭issue, 否则请通过issue页面按钮关闭issue!`,
				cuAccount), issueTmp.IssueNum, owner, issueTmp.Repo, token)
			return
		}
		cveCenter := models.VulnCenter{CveId: issueTmp.CveId, CveNum: issueTmp.CveNum}
		err := models.GetVulnCenterByCid(&cveCenter, "cve_id", "cve_num")
		if err != nil {
			return
		}
		issueTmp.IssueLabel = unfixed
		issueTmp.StatusName = "open"
		assignee := getMaintainer(issueTmp.Repo, cuAccount, issueTmp.Assignee)
		issuePrFlag := VerifyIssueAsPr(issueTmp, cveCenter, false, assignee, cuAccount)
		if issuePrFlag {
			issueTmp.IssueLabel = fixed
			issueTmp.StatusName = "closed"
			taskhandler.AddCommentToIssue(fmt.Sprintf(`@%v 你已审核模板内容,cve-manager 将关闭issue!`,
				cuAccount), issueTmp.IssueNum, owner, issueTmp.Repo, token)
			_, issueErr := taskhandler.UpdateIssueToGit(token, owner, issueTmp.Repo,
				cveCenter, *issueTmp)
			if issueErr == nil {
				logs.Info("Initiate an issue to close, issuetmp: ", issueTmp)
			} else {
				logs.Error("issue close operation failed, issuetmp: ", issueTmp, ",issueErr: ", issueErr)
				return
			}
			issueTmp.SaAuditFlag = 1
			issueTmp.Status = 3
			if isNormalCloseIssue(issueTmp.CveId, issueTmp.IssueStatus) {
				issueTmp.IssueStatus = 2
				cveCenter.IsExport = 3
			} else {
				issueTmp.IssueStatus = 6
				cveCenter.IsExport = 2
			}
			updateBool := updateTempAndCenter(*issueTmp, cveCenter, token, owner)
			if !updateBool {
				return
			}
		}
		return
	}
}

func handleIssueComment(payload models.CommentPayload) {
	if payload.Issue == nil || payload.Comment == nil {
		return
	}
	if payload.Comment.User == nil {
		return
	}
	// The default timeout for receiving hooks
	logs.Info("payload.Comment: ", payload.Comment, ", Number: ", payload.Issue.Number, "id: ", payload.Issue.Id)
	issueNum := payload.Issue.Number           //issue number string
	issueId := payload.Issue.Id                // issue id int64
	cBody := payload.Comment.Body              //Comment subject
	cuAccount := payload.Comment.User.UserName //gitee domain address
	repoPath := payload.Issue.Repository.Path
	cmdRej := beego.AppConfig.DefaultString("rejectCmd", "/reject")
	cmdApe := beego.AppConfig.DefaultString("approveCmd", "/approve")
	cmdClose := beego.AppConfig.DefaultString("closeCmd", "/close")
	cmdError := beego.AppConfig.DefaultString("errorCmd", "/error")
	cmdAutoPr := beego.AppConfig.String("autoPrCmd")
	cmdGetCve := beego.AppConfig.String("getCveCmd")
	cmdFeedBack := beego.AppConfig.String("feedBackCmd")
	if issueNum == "" || cuAccount == "" || cBody == "" {
		logs.Error("Data has null values: issueNum, cuAccount, cBody: ", issueNum, cuAccount, cBody)
		return
	}
	// Ignore this comment
	botCuAccountStr := beego.AppConfig.String("cve::bot_cu_account")
	botCuAccountList := strings.Split(botCuAccountStr, ",")
	if len(botCuAccountList) > 0 {
		for _, botCu := range botCuAccountList {
			if cuAccount == botCu {
				logs.Error(cuAccount, ", Ignore this comment")
				return
			}
		}
	}
	issueTmp := models.IssueTemplate{IssueNum: issueNum, IssueId: issueId}
	err := models.GetIssueTemplateByColName(&issueTmp, "issue_num", "issue_id")
	if err != nil {
		logs.Error("GetErr: ", err, ",issueTmp: ", issueTmp)
		return
	}
	agencyPram := AgencyPrams{}
	fixed := beego.AppConfig.String("labelFixed")
	unfixed := beego.AppConfig.String("labelUnFix")
	path := issueTmp.Repo
	vc := models.VulnCenter{CveId: issueTmp.CveId}
	vcErr := models.GetVulnCenterByCid(&vc, "CveId")
	if vcErr != nil {
		logs.Error("GetVulnCenterByCid, vcErr: ", vcErr, ",CveId: ", issueTmp.CveId)
		return
	}
	owner, accessToken := common.GetOwnerAndToken(vc.OrganizationID)
	if vc.OrganizationID == 2 {
		if len(path) < 2 {
			path = beego.AppConfig.String("opengauss::gauss_issue_path")
		}
		cBody = strings.ReplaceAll(cBody, util.KwOpenGaussScore, util.KwOpenEulerScore)
	} else if vc.OrganizationID == 3 {
		// Query the repo that needs to submit an issue
		cBody = strings.ReplaceAll(cBody, util.KwMindSporeScore, util.KwOpenEulerScore)
	} else if vc.OrganizationID == 4 {
		cBody = strings.ReplaceAll(cBody, util.KwLooKengScore, util.KwOpenEulerScore)
	}
	if len(repoPath) > 1 && repoPath != path {
		vc.PackName = repoPath
		vc.RepoName = issueTmp.OwnedComponent
		models.UpdateVulnCenter(&vc, "PackName", "RepoName")
		issueTmp.Repo = repoPath
		models.UpdateIssueTemplate(&issueTmp, "Repo")
		path = repoPath
	}
	if payload.Issue.StateName == "已挂起" {
		logs.Error("The current issue has been suspended and will not be processed, payload: ", payload)
		issueTmp.Status = 5
		models.UpdateIssueTemplate(&issueTmp, "Status")
		taskhandler.AddCommentToIssue(fmt.Sprintf(CommentRejectedState, cuAccount, payload.Issue.StateName),
			issueTmp.IssueNum, owner, path, accessToken)
		return
	}
	if payload.Issue.StateName == "已拒绝" {
		logs.Error("The current issue has been rejected and will not be processed, payload: ", payload)
		issueTmp.Status = 4
		models.UpdateIssueTemplate(&issueTmp, "Status")
		taskhandler.AddCommentToIssue(fmt.Sprintf(CommentRejectedState, cuAccount, payload.Issue.StateName),
			issueTmp.IssueNum, owner, path, accessToken)
		return
	}
	if strings.HasPrefix(cBody, cmdRej) {
		//Review rejected Add comment @Analyst
		if !isReviewer(cuAccount) {
			return
		}
		if issueTmp.OpenEulerScore != issueTmp.NVDScore && issueTmp.NVDScore > 0 &&
			issueTmp.OpenEulerScore > 0 {
			err = changeOpenEulerScoreStatus(issueTmp.CveId, 2)
			if err != nil {
				logs.Error("changeOpenEulerScoreStatus, 1.err:", err)
			}
			issueTmp.OpAuditFlag = 2
			err = models.UpdateIssueTemplate(&issueTmp, "op_audit_flag")
			if err != nil {
				logs.Error("UpdateIssueTemplate, 2.err:", err)
			}
			taskhandler.AddCommentToIssue(fmt.Sprintf(ReviewRejectScore, issueTmp.Assignee, cuAccount),
				issueTmp.IssueNum, owner, path, accessToken)
		}
	} else if strings.HasPrefix(cBody, cmdApe) || strings.HasPrefix(cBody, cmdClose) {
		if issueTmp.Status == 3 {
			// The issue has been closed and cannot be operated again
			logs.Error("The issue has been closed and cannot be operated again,issuetmp: ", issueTmp)
			return
		}
		if vc.OrganizationID == 4 {
			comLock.Lock()
			looKengMaintainerApprove(&issueTmp, cuAccount, owner, accessToken, fixed, unfixed, path, vc)
			comLock.Unlock()
		} else if vc.OrganizationID == 3 {
			comLock.Lock()
			sporeMaintainerApprove(&issueTmp, cuAccount, owner, accessToken, fixed, unfixed, path, vc)
			comLock.Unlock()
		} else if vc.OrganizationID == 2 {
			comLock.Lock()
			gaussMaintainerApprove(&issueTmp, cuAccount, owner, accessToken, fixed, unfixed, path, vc)
			comLock.Unlock()
		} else {
			approveFlag := true
			if issueTmp.OpenEulerScore != issueTmp.NVDScore && issueTmp.NVDScore > 0 &&
				issueTmp.OpAuditFlag != 1 && issueTmp.OpenEulerScore > 0 {
				//Approved to modify the rating status
				approveFlag = openEulerScoreReview(&issueTmp, cuAccount, owner, accessToken)
			}
			if approveFlag {
				mtAuditFlag := false
				// Analysis command belongs to the time period
				maintainerList, mainOk := models.QueryRepoAllMaintainer(issueTmp.Repo)
				if mainOk && len(maintainerList) > 0 {
					for _, v := range maintainerList {
						if util.TrimString(v.MemberName) == cuAccount {
							mtAuditFlag = true
							break
						}
					}
				}
				if mtAuditFlag {
					comLock.Lock()
					maintainerApprove(&issueTmp, cuAccount, owner, accessToken, fixed, unfixed, vc.OrganizationID)
					comLock.Unlock()
				} else {
					comLock.Lock()
					securityApprove(&issueTmp, cuAccount, owner, accessToken, fixed, unfixed, vc.OrganizationID)
					comLock.Unlock()
				}
			}
		}
	} else if strings.HasPrefix(cBody, cmdError) {
		c := strings.TrimPrefix(cBody, cmdError)
		c = strings.TrimSpace(c)
		issueTmp.ErrorDescription = c
		issueTmp.UpdateTime = time.Now()
		//update issue tpl
		err = models.UpdateIssueTemplate(&issueTmp, "error_description", "update_time")
		if err != nil {
			logs.Error("updateIssueErr: ", err, "issueTmp: ", issueTmp)
			return
		}
	} else if strings.HasPrefix(cBody, cmdAutoPr) {
		if vc.OrganizationID == 1 {
			PostCveAgency(issueTmp, agencyPram)
		}
	} else if strings.HasPrefix(cBody, cmdFeedBack) {
		if vc.OrganizationID == 1 {
			bodyList := strings.Split(cBody, " ")
			if len(bodyList) > 2 {
				agencyPram.CveUrl = bodyList[1]
				agencyPram.PatchUrl = bodyList[2]
			}
			PostCveAgency(issueTmp, agencyPram)
		}
	} else if strings.HasPrefix(cBody, cmdGetCve) {
		PostTriggerGetCve(issueTmp, owner, accessToken, cuAccount)
	} else {
		if payload.Issue.State == "closed" || payload.Issue.State == "rejected" ||
			payload.Issue.State == "已完成" || payload.Issue.State == "已拒绝" {
			logs.Error("Cannot edit comment, value: ", payload.Issue)
			return
		}
		cBody = strings.ReplaceAll(cBody, "：", ":")
		comLock.Lock()
		analysisComment(owner, accessToken, path, cuAccount, cBody, &payload, issueTmp, vc.OrganizationID)
		comLock.Unlock()
	}
}

func PostCveAgency(issueTmp models.IssueTemplate, agencyPram AgencyPrams) {
	// Trigger third-party data generation
	agencyUrl := beego.AppConfig.String("cveagency::url")
	agencyReq := make(map[string]interface{}, 0)
	agencyReq["CveNum"] = issueTmp.CveNum
	agencyReq["PackName"] = issueTmp.OwnedComponent
	agencyReq["PackVersion"] = issueTmp.OwnedVersion
	agencyReq["CveUrl"] = agencyPram.CveUrl
	agencyReq["PatchUrl"] = agencyPram.PatchUrl
	if len(issueTmp.AffectedVersion) > 0 {
		versionList := strings.Split(issueTmp.AffectedVersion, ",")
		if len(versionList) > 0 {
			vSlice := []string{}
			for _, vl := range versionList {
				vs := strings.Split(vl, ":")
				if len(vs) > 0 {
					vSlice = append(vSlice, vs[0])
				}
			}
			if len(vSlice) > 0 {
				agencyReq["AffectBranch"] = strings.Join(vSlice, " ")
			}
		}
	} else {
		agencyReq["AffectBranch"] = ""
	}
	agencyReq["IssueNumber"] = issueTmp.IssueNum
	util.HTTPPostCom(agencyReq, agencyUrl)
}

func PostTriggerGetCve(issueTmp models.IssueTemplate, owner, accessToken, cuAccount string) {
	// Trigger third-party data generation
	cc := ""
	if len(issueTmp.CveNum) > 0 {
		resp := tabletask.PullCve(issueTmp.CveNum)
		if resp == 1 {
			cc = fmt.Sprintf(CommentGetNvdCveSuccess, cuAccount)
		} else {
			cc = fmt.Sprintf(CommentGetNvdCveFailed, cuAccount)
		}
		if len(cc) > 1 {
			taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, issueTmp.Repo, accessToken)
		}
		vc := models.VulnCenter{CveId: issueTmp.CveId}
		vcErr := models.GetVulnCenterByCid(&vc, "CveId")
		if vcErr != nil {
			logs.Error("GetVulnCenterByCid, vcErr: ", vcErr, ",CveId: ", issueTmp.CveId)
			return
		}
		models.UpdateIssueStatus(vc, 1)
		issueErr := task.SyncCreateIssue()
		if issueErr != nil {
			logs.Error("SyncCveAndIssue, SyncCreateIssue, err: ", issueErr)
		}
	}
}

func isReviewer(path string) bool {
	sr := models.SecurityReviewer{NameSpace: path}
	return sr.Read("name_space")
}

func isGaussReviewer(path string) bool {
	sr := models.OpenGaussSecurityReviewer{NameSpace: path}
	return sr.Read("name_space")
}

func isMindSporeReviewer(path string) bool {
	sr := models.MindSporeSecurityReviewer{NameSpace: path}
	return sr.Read("name_space")
}

func isLooKengReviewer(path string) bool {
	sr := models.OpenLookengSecurityReviewer{NameSpace: path}
	return sr.Read("name_space")
}

func analysisComment(owner, accessToken, path string, cuAccount string, cBody string,
	payload *models.CommentPayload, issueTmp models.IssueTemplate, OrganizationID int8) {
	if issueTmp.Status == 3 {
		// The issue has been closed and cannot be operated again
		logs.Error("The issue has been closed and cannot be operated again,issuetmp: ", issueTmp)
		return
	}
	canVerfy := false
	issueTmp.MtAuditFlag = 1
	//is Analyst comment and content start with '/analysis'
	vMap := util.ExtractCommentAnalysisAllValue(cBody, OrganizationID)
	if len(vMap) > 0 {
		canVerfy = true
		cols := make([]string, 0)
		for k, v := range vMap {
			switch k {
			case "cve_analysis":
				if v != "" && len(v) > 1 {
					issueTmp.CveAnalysis = common.DeletePreAndSufSpace(v)
					cols = append(cols, k)
				}
			case "principle_analysis":
				issueTmp.PrincipleAnalysis = v
				cols = append(cols, k)
			case "openeuler_score":
				fv, err := strconv.ParseFloat(v, 64)
				if err == nil && fv > 0 {
					if issueTmp.OpenEulerScore > 0 && issueTmp.OpenEulerScore != fv {
						issueTmp.OpAuditFlag = 0
						cols = append(cols, "op_audit_flag")
					}
					issueTmp.OpenEulerScore = fv
					cols = append(cols, k)
				}
			case "openeuler_vector":
				if v != "" && len(v) > 1 {
					issueTmp.OpenEulerVector = common.DeletePreAndSufSpace(v)
					cols = append(cols, k)
				}
			case "affected_version":
				if v != "" && len(v) > 1 {
					if paraAffectBrandBool(v) {
						issueTmp.AffectedVersion = v
						cols = append(cols, k)
					}
				}
			case "abi_version":
				if v != "" && len(v) > 1 {
					if taskhandler.ParaAffectAbiBool(v) {
						issueTmp.AbiVersion = v
						cols = append(cols, k)
					}
				}
			case "solution":
				issueTmp.Solution = v
				cols = append(cols, k)
			}
		}
		if len(cols) > 0 {
			cols = append(cols, "mt_audit_flag")
			err := models.UpdateIssueTemplate(&issueTmp, cols...)
			if err != nil {
				logs.Error("uperr: ", err, ",issueTmp: ", issueTmp)
			} else {
				if _, ok := vMap["openeuler_vector"]; ok {
					err := saveVectorData(vMap["openeuler_vector"], issueTmp.CveId)
					if err != nil {
						logs.Error("saveVectorData, err: ", err)
					}
				}
				if _, ok := vMap["openeuler_score"]; ok {
					//更新分数到 score
					score, err := models.QueryIssueScore(issueTmp.CveId)
					if err != nil {
						logs.Error("queryErr: ", err, "cveId: ", issueTmp.CveId)
					} else {
						score.OpenEulerScore = issueTmp.OpenEulerScore
						score.Ostatus = 1
						err := models.UpdateScore(&score, "openeuler_score", "o_score_status")
						if err != nil {
							logs.Error("upErr: ", err, ",UpdateScore, score: ", score)
						}
					}
				}
			}
			// update gitee issue
			commentUpdateIssue(issueTmp, owner, accessToken, path)
		}
		if _, ok := vMap["issue_package"]; ok {
			// handle comment package
			err := handleCommentPackage(vMap["issue_package"], issueTmp.CveId)
			if err != nil {
				logs.Error("handleCommentPackage, err: ", err)
			}
		}
	}
	if canVerfy {
		//Check whether the data is legal
		checkFunc := checkIssueAnalysisComplete
		if OrganizationID == 2 {
			checkFunc = checkGaussIssueAnalysisComplete
		} else if OrganizationID == 3 {
			checkFunc = checkSporeIssueAnalysisComplete
		} else if OrganizationID == 4 {
			checkFunc = checkLooKengIssueAnalysisComplete
		}
		if msg, tb, ok := checkFunc(&issueTmp); !ok {
			//send comment to issue
			issueTmp.IssueStatus = 1
			err := models.UpdateIssueTemplate(&issueTmp, "issue_status")
			if err != nil {
				logs.Error("UpdateIssueTemplate, upErr: ", err, ",issueTmp: ", issueTmp)
			}
			assignee := ""
			if cuAccount != "" && len(cuAccount) > 1 {
				assignee = cuAccount
			} else {
				assignee = issueTmp.Assignee
			}
			msg = fmt.Sprintf(CommentAnalysisCplTpl, assignee, msg)
			taskhandler.AddCommentToIssue(msg, issueTmp.IssueNum, owner, path, accessToken)
		} else {
			if OrganizationID == 1 {
				//1. change issue status
				issueTmp.IssueStatus = 3
				//2. Are the cvsScore and openEuler score  equal .If not equal, notify the auditor to review .
				var na string
				if issueTmp.OpenEulerScore != issueTmp.NVDScore && issueTmp.OpenEulerScore > 0 &&
					issueTmp.NVDScore > 0 && issueTmp.OpAuditFlag == 0 {
					na = "\n**因OpenEulerScore与NvdScore不一致,分析内容需审核,请等待安全组审核!**"
					//Notify the responsible person for review
					notifyAuditorReview(payload, issueTmp)
				} else {
					if issueTmp.MtAuditFlag == 0 {
						maintainerList, mainOk := models.QueryRepoAllMaintainer(issueTmp.Repo)
						assList := []string{}
						if mainOk && len(maintainerList) > 0 {
							for _, v := range maintainerList {
								assList = append(assList, "@"+v.MemberName+" ")
								content := fmt.Sprintf("%v 仓库的CVE和安全问题的ISSUE,CVE编号: %v, "+
									"已经完成了模板填写,需要您对填写的内容进行审核,审核通过才能进行后续操作.", issueTmp.Repo, issueTmp.CveNum)
								taskhandler.SendPrivateLetters(accessToken, content, v.MemberName)
							}
						}
						assignee := ""
						if len(assList) > 0 {
							assignee = strings.Join(assList, ",")
						} else {
							assignee = "@" + issueTmp.Assignee
						}
						na = "\n**请确认模板分析内容的准确性与完整性, 确认无误后,请在评论区输入: /approve, 否则无法关闭当前issue.**"
						cc := fmt.Sprintf(ContentReview, assignee) + tb + na
						taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, path, accessToken)
					} else {
						na = "\n**请确认分析内容的准确性, 确认无误后, 您可以进行后续步骤, 否则您可以继续分析.**"
						cc := fmt.Sprintf(AnalysisComplete, issueTmp.Assignee) + tb + na
						taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, path, accessToken)
					}
					// change score status
					err := changeOpenEulerScoreStatus(issueTmp.CveId, 3)
					if err != nil {
						logs.Error("changeOpenEulerScoreStatus, err: ", err, ",issueTmp: ", issueTmp)
					}
				}
			} else {
				na := "\n**请确认分析内容的准确性, 确认无误后, 您可以进行后续步骤, 否则您可以继续分析.**"
				cc := fmt.Sprintf(AnalysisComplete, issueTmp.Assignee) + tb + na
				taskhandler.AddCommentToIssue(cc, issueTmp.IssueNum, owner, path, accessToken)
				// change score status
				err := changeOpenEulerScoreStatus(issueTmp.CveId, 3)
				if err != nil {
					logs.Error("changeOpenEulerScoreStatus, err: ", err, ",issueTmp: ", issueTmp)
				}
			}
		}
		err := models.UpdateIssueTemplate(&issueTmp, "issue_status", "mt_audit_flag")
		if err != nil {
			logs.Error("UpdateIssueTemplate, updErr: ", err, ",issueTmp: ", issueTmp)
		}
	}
}

func notifyAuditorReview(payload *models.CommentPayload, issueTmp models.IssueTemplate) {
	//Notify the responsible person for review
	list, err := models.GetSecurityReviewerList()
	if err != nil {
		logs.Error("GetSecurityReviewerList, err: ", err)
		return
	}
	if len(list) == 0 {
		return
	}
	accessToken := os.Getenv("GITEE_TOKEN")
	content := fmt.Sprintf(ReviewPrivateLettersTpl,
		payload.Issue.Title, payload.Issue.HtmlUrl, issueTmp.NVDScore, issueTmp.OpenEulerScore)
	owner := beego.AppConfig.String("gitee::owner")
	//path := beego.AppConfig.String("gitee::path")
	path := issueTmp.Repo
	ns := make([]string, len(list))
	for k, v := range list {
		ns[k] = "@" + v.NameSpace + " "
		taskhandler.SendPrivateLetters(accessToken, content, v.NameSpace)
		//add @comment
	}
	msg := fmt.Sprintf(CommentReviewTpl, strings.Join(ns, ","))
	taskhandler.AddCommentToIssue(msg, issueTmp.IssueNum, owner, path, accessToken)
}

func changeOpenEulerScoreStatus(cveID int64, status int8) error {
	score, err := models.QueryIssueScore(cveID)
	if err != nil {
		return err
	}
	score.Ostatus = status
	err = models.UpdateScore(&score, "o_score_status")
	return err
}

func checkIssueAnalysisComplete(i *models.IssueTemplate) (msg, tbStr string, ok bool) {
	tb :=
		`| 状态  | 需分析 | 内容 |
|:--:|:--:|---------|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
`

	if i == nil {
		logs.Error("issue template is nil")
		return msg, "", false
	}
	ok = true
	tbContent := make([]interface{}, 15)
	if util.TrimString(i.CveAnalysis) == "" || len(util.TrimString(i.CveAnalysis)) < 1 {
		msg = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		ok = false
		return
	}
	tbContent[0] = "已分析"
	tbContent[1] = "1.影响性分析说明"
	tbContent[2] = util.TrimStringNR(i.CveAnalysis)
	affectedVersionFlag := 1
	if i.AffectedVersion != "" {
		versionfFlag := true
		affectedVersionArry := strings.Split(i.AffectedVersion, ",")
		if len(affectedVersionArry) > 0 {
			for _, affectx := range affectedVersionArry {
				affect := common.BranchVersionRep(affectx)
				versionArry := strings.Split(affect, ":")
				if len(versionArry) > 1 {
					if versionArry[1] == "受影响" || versionArry[1] == "不受影响" {
						if versionArry[1] == "受影响" {
							affectedVersionFlag = 2
						}
						continue
					} else {
						affectedVersionFlag = 3
						versionfFlag = false
						break
					}
				} else {
					affectedVersionFlag = 3
					versionfFlag = false
					break
				}
			}
		}
		if !versionfFlag {
			msg = fmt.Sprintf("3.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			ok = false
			return
		}
		if versionfFlag {
			tbContent[9] = "已分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		} else {
			tbContent[9] = "待分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		}
	} else {
		tbContent[9] = "已分析"
		tbContent[10] = "3.受影响版本排查"
		tbContent[11] = ""
	}
	if affectedVersionFlag == 1 {
		tbContent[3] = "已分析"
		tbContent[4] = "2.openEulerScore"
		tbContent[5] = i.OpenEulerScore
		tbContent[6] = "已分析"
		tbContent[7] = "2.openEulerVector"
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	} else {
		if i.OpenEulerScore == 0.0 {
			msg = fmt.Sprintf("2.openEulerScore=> 没有填写或正确填写(0-10)")
			ok = false
			return
		}
		tbContent[3] = "已分析"
		tbContent[4] = "2.openEulerScore"
		tbContent[5] = i.OpenEulerScore

		if i.OpenEulerVector == "" || len(i.OpenEulerVector) < 1 {
			msg = fmt.Sprintf("2.openEulerVector=> 没有正确填写")
			ok = false
			return
		}
		tbContent[6] = "已分析"
		tbContent[7] = "2.openEulerVector"
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	}
	if i.AbiVersion != "" {
		versionAbiFlag := true
		abiVersionArry := strings.Split(i.AbiVersion, ",")
		if len(abiVersionArry) > 0 {
			for _, affectx := range abiVersionArry {
				affect := common.BranchVersionRep(affectx)
				versionArry := strings.Split(affect, ":")
				if len(versionArry) > 1 {
					if versionArry[1] == "是" || versionArry[1] == "否" {
						continue
					} else {
						versionAbiFlag = false
						break
					}
				} else {
					versionAbiFlag = false
					break
				}
			}
		}
		if !versionAbiFlag {
			msg = fmt.Sprintf("4.修复是否涉及abi变化(是/否)=> 没有分析或未按正确格式填写:%v", i.AbiVersion)
			ok = false
			return
		}
		if versionAbiFlag {
			tbContent[12] = "已分析"
			tbContent[13] = "4.修复是否涉及abi变化"
			tbContent[14] = util.TrimStringNR(i.AbiVersion)
		} else {
			tbContent[12] = "待分析"
			tbContent[13] = "4.修复是否涉及abi变化"
			tbContent[14] = util.TrimStringNR(i.AbiVersion)
		}
	} else {
		tbContent[12] = "已分析"
		tbContent[13] = "4.修复是否涉及abi变化"
		tbContent[14] = ""
	}
	tbStr = fmt.Sprintf(tb, tbContent...)
	return
}

func checkGaussIssueAnalysisComplete(i *models.IssueTemplate) (msg, tbStr string, ok bool) {
	tb :=
		`| 状态  | 需分析 | 内容 |
|:--:|:--:|---------|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
`
	if i == nil {
		logs.Error("issue template is nil")
		return msg, "", false
	}
	ok = true
	tbContent := make([]interface{}, 12)
	if util.TrimString(i.CveAnalysis) == "" || len(util.TrimString(i.CveAnalysis)) < 1 {
		msg = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		ok = false
		return
	}
	tbContent[0] = "已分析"
	tbContent[1] = "1.影响性分析说明"
	tbContent[2] = util.TrimStringNR(i.CveAnalysis)
	affectedVersionFlag := 1
	if i.AffectedVersion != "" {
		versionfFlag := true
		affectedVersionArry := strings.Split(i.AffectedVersion, ",")
		if len(affectedVersionArry) > 0 {
			for _, affect := range affectedVersionArry {
				versionArry := strings.Split(affect, ":")
				if len(versionArry) > 1 {
					if versionArry[1] == "受影响" || versionArry[1] == "不受影响" {
						if versionArry[1] == "受影响" {
							affectedVersionFlag = 2
						}
						continue
					} else {
						affectedVersionFlag = 3
						versionfFlag = false
						break
					}
				} else {
					affectedVersionFlag = 3
					versionfFlag = false
					break
				}
			}
		}
		if !versionfFlag {
			msg = fmt.Sprintf("3.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			ok = false
			return
		}
		if versionfFlag {
			tbContent[9] = "已分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		} else {
			tbContent[9] = "待分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		}
	} else {
		tbContent[9] = "已分析"
		tbContent[10] = "3.受影响版本排查"
		tbContent[11] = ""
	}
	if affectedVersionFlag == 1 {
		tbContent[3] = "已分析"
		tbContent[4] = "2.openGaussScore"
		tbContent[5] = i.OpenEulerScore
		tbContent[6] = "已分析"
		tbContent[7] = "2.openGaussVector"
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	} else {
		if i.OpenEulerScore == 0.0 {
			msg = fmt.Sprintf("2.openGaussScore=> 没有填写或正确填写(0-10)")
			ok = false
			return
		}
		tbContent[3] = "已分析"
		tbContent[4] = "2.openGaussScore"
		tbContent[5] = i.OpenEulerScore

		if i.OpenEulerVector == "" || len(i.OpenEulerVector) < 1 {
			msg = fmt.Sprintf("2.openGaussVector=> 没有正确填写")
			ok = false
			return
		}
		tbContent[6] = "已分析"
		tbContent[7] = "2.openGaussVector"
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	}
	tbStr = fmt.Sprintf(tb, tbContent...)
	return
}

func checkSporeIssueAnalysisComplete(i *models.IssueTemplate) (msg, tbStr string, ok bool) {
	tb :=
		`| 状态  | 需分析 | 内容 |
|:--:|:--:|---------|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
`
	if i == nil {
		logs.Error("issue template is nil")
		return msg, "", false
	}
	ok = true
	tbContent := make([]interface{}, 12)
	if util.TrimString(i.CveAnalysis) == "" || len(util.TrimString(i.CveAnalysis)) < 1 {
		msg = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		ok = false
		return
	}
	tbContent[0] = "已分析"
	tbContent[1] = "1.影响性分析说明"
	tbContent[2] = util.TrimStringNR(i.CveAnalysis)
	affectedVersionFlag := 1
	if i.AffectedVersion != "" {
		versionfFlag := true
		affectedVersionArry := strings.Split(i.AffectedVersion, ",")
		if len(affectedVersionArry) > 0 {
			for _, affect := range affectedVersionArry {
				versionArry := strings.Split(affect, ":")
				if len(versionArry) > 1 {
					if versionArry[1] == "受影响" || versionArry[1] == "不受影响" {
						if versionArry[1] == "受影响" {
							affectedVersionFlag = 2
						}
						continue
					} else {
						affectedVersionFlag = 3
						versionfFlag = false
						break
					}
				} else {
					affectedVersionFlag = 3
					versionfFlag = false
					break
				}
			}
		}
		if !versionfFlag {
			msg = fmt.Sprintf("3.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			ok = false
			return
		}
		if versionfFlag {
			tbContent[9] = "已分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		} else {
			tbContent[9] = "待分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		}
	} else {
		tbContent[9] = "已分析"
		tbContent[10] = "3.受影响版本排查"
		tbContent[11] = ""
	}
	if affectedVersionFlag == 1 {
		tbContent[3] = "已分析"
		tbContent[4] = "2.MindSporeScore"
		tbContent[5] = i.OpenEulerScore
		tbContent[6] = "已分析"
		tbContent[7] = "2.MindSporeVector"
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	} else {
		if i.OpenEulerScore == 0.0 {
			msg = fmt.Sprintf("2.MindSporeScore=> 没有填写或正确填写(0-10)")
			ok = false
			return
		}
		tbContent[3] = "已分析"
		tbContent[4] = "2.MindSporeScore"
		tbContent[5] = i.OpenEulerScore
		if i.OpenEulerVector == "" || len(i.OpenEulerVector) < 1 {
			msg = fmt.Sprintf("2.MindSporeVector=> 没有正确填写")
			ok = false
			return
		}
		tbContent[6] = "已分析"
		tbContent[7] = "2.MindSporeVector"
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	}
	tbStr = fmt.Sprintf(tb, tbContent...)
	return
}

func checkLooKengIssueAnalysisComplete(i *models.IssueTemplate) (msg, tbStr string, ok bool) {
	tb :=
		`| 状态  | 需分析 | 内容 |
|:--:|:--:|---------|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
`
	if i == nil {
		logs.Error("issue template is nil")
		return msg, "", false
	}
	ok = true
	tbContent := make([]interface{}, 12)
	if util.TrimString(i.CveAnalysis) == "" || len(util.TrimString(i.CveAnalysis)) < 1 {
		msg = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		ok = false
		return
	}
	tbContent[0] = "已分析"
	tbContent[1] = "1.影响性分析说明"
	tbContent[2] = util.TrimStringNR(i.CveAnalysis)
	affectedVersionFlag := 1
	if i.AffectedVersion != "" {
		versionfFlag := true
		affectedVersionArry := strings.Split(i.AffectedVersion, ",")
		if len(affectedVersionArry) > 0 {
			for _, affect := range affectedVersionArry {
				versionArry := strings.Split(affect, ":")
				if len(versionArry) > 1 {
					if versionArry[1] == "受影响" || versionArry[1] == "不受影响" {
						if versionArry[1] == "受影响" {
							affectedVersionFlag = 2
						}
						continue
					} else {
						affectedVersionFlag = 3
						versionfFlag = false
						break
					}
				} else {
					affectedVersionFlag = 3
					versionfFlag = false
					break
				}
			}
		}
		if !versionfFlag {
			msg = fmt.Sprintf("3.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			ok = false
			return
		}
		if versionfFlag {
			tbContent[9] = "已分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		} else {
			tbContent[9] = "待分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		}
	} else {
		tbContent[9] = "已分析"
		tbContent[10] = "3.受影响版本排查"
		tbContent[11] = ""
	}
	if affectedVersionFlag == 1 {
		tbContent[3] = "已分析"
		tbContent[4] = "2.openLooKengScore"
		tbContent[5] = i.OpenEulerScore
		tbContent[6] = "已分析"
		tbContent[7] = "2.openLooKengVector"
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	} else {
		if i.OpenEulerScore == 0.0 {
			msg = fmt.Sprintf("2.openLooKengScore=> 没有填写或正确填写(0-10)")
			ok = false
			return
		}
		tbContent[3] = "已分析"
		tbContent[4] = "2.openLooKengScore"
		tbContent[5] = i.OpenEulerScore
		if i.OpenEulerVector == "" || len(i.OpenEulerVector) < 1 {
			msg = fmt.Sprintf("2.openLooKengVector=> 没有正确填写")
			ok = false
			return
		}
		tbContent[6] = "已分析"
		tbContent[7] = "2.openLooKengVector"
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	}
	tbStr = fmt.Sprintf(tb, tbContent...)
	return
}

func checkIssueClosedAnalysisComplete(i *models.IssueTemplate) (msg, tbStr string, ok bool) {
	tb :=
		`| 状态  | 需分析 | 内容 |
|:--:|:--:|---------|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
`
	if i == nil {
		logs.Error("issue template is nil")
		return msg, "", false
	}
	ok = true
	tbContent := make([]interface{}, 15)
	if util.TrimString(i.CveAnalysis) == "" || len(util.TrimString(i.CveAnalysis)) < 2 {
		tbContent[0] = "待分析"
		tbContent[1] = "1.影响性分析说明"
		tbContent[2] = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		msg = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		ok = false
	} else {
		tbContent[0] = "已分析"
		tbContent[1] = "1.影响性分析说明"
		tbContent[2] = util.TrimStringNR(i.CveAnalysis)
	}
	affectedVersionFlag := 1
	if i.AffectedVersion != "" {
		versionfFlag := true
		affectedVersionArry := strings.Split(i.AffectedVersion, ",")
		if len(affectedVersionArry) > 0 {
			for _, affectx := range affectedVersionArry {
				affect := common.BranchVersionRep(affectx)
				versionArry := strings.Split(affect, ":")
				if len(versionArry) > 1 {
					if versionArry[1] == "受影响" || versionArry[1] == "不受影响" {
						if versionArry[1] == "受影响" {
							affectedVersionFlag = 2
						}
						continue
					} else {
						affectedVersionFlag = 3
						versionfFlag = false
						break
					}
				} else {
					affectedVersionFlag = 3
					versionfFlag = false
					break
				}
			}
		}
		if !versionfFlag {
			tbContent[9] = "待分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = fmt.Sprintf("3.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			msg = fmt.Sprintf("3.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			ok = false
		} else {
			tbContent[9] = "已分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		}
	} else {
		tbContent[9] = "已分析"
		tbContent[10] = "3.受影响版本排查"
		tbContent[11] = ""
	}
	if affectedVersionFlag == 1 {
		tbContent[3] = "已分析"
		tbContent[4] = "2.openEulerScore"
		tbContent[5] = i.OpenEulerScore
		tbContent[6] = "已分析"
		tbContent[7] = "2.openEulerVector"
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	} else {
		if i.OpenEulerScore == 0.0 {
			tbContent[3] = "待分析"
			tbContent[4] = "2.openEulerScore"
			tbContent[5] = fmt.Sprintf("2.openEulerScore=> 没有填写或正确填写(0-10)")
			msg = fmt.Sprintf("2.openEulerScore=> 没有填写或正确填写(0-10)")
			ok = false
		} else {
			tbContent[3] = "已分析"
			tbContent[4] = "2.openEulerScore"
			tbContent[5] = i.OpenEulerScore
		}
		if util.TrimString(i.OpenEulerVector) == "" || len(util.TrimString(i.OpenEulerVector)) < 1 {
			tbContent[6] = "待分析"
			tbContent[7] = "2.openEulerVector"
			tbContent[8] = fmt.Sprintf("2.openEulerVector=> 没有正确填写")
			msg = fmt.Sprintf("2.openEulerVector=> 没有正确填写")
			ok = false
		} else {
			tbContent[6] = "已分析"
			tbContent[7] = "2.openEulerVector"
			tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
		}
	}
	if i.AbiVersion != "" {
		versionAbiFlag := true
		abiVersionArry := strings.Split(i.AbiVersion, ",")
		if len(abiVersionArry) > 0 {
			for _, affectx := range abiVersionArry {
				affect := common.BranchVersionRep(affectx)
				versionArry := strings.Split(affect, ":")
				if len(versionArry) > 1 {
					if versionArry[1] == "是" || versionArry[1] == "否" {
						continue
					} else {
						versionAbiFlag = false
						break
					}
				} else {
					versionAbiFlag = false
					break
				}
			}
		}
		if !versionAbiFlag {
			tbContent[12] = "待分析"
			tbContent[13] = "4.修复是否涉及abi变化"
			tbContent[14] = fmt.Sprintf("4.修复是否涉及abi变化(是/否)=> 没有分析或未按正确格式填写:%v", i.AbiVersion)
			msg = fmt.Sprintf("4.修复是否涉及abi变化(是/否)=> 没有分析或未按正确格式填写:%v", i.AbiVersion)
			ok = false
		} else {
			tbContent[12] = "已分析"
			tbContent[13] = "4.修复是否涉及abi变化"
			tbContent[14] = util.TrimStringNR(i.AbiVersion)
		}
	} else {
		tbContent[12] = "已分析"
		tbContent[13] = "4.修复是否涉及abi变化"
		tbContent[14] = ""
	}
	tbStr = fmt.Sprintf(tb, tbContent...)
	return
}

func checkGaussIssueClosedAnalysisComplete(i *models.IssueTemplate) (msg, tbStr string, ok bool) {
	tb :=
		`| 状态  | 需分析 | 内容 |
|:--:|:--:|---------|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
`
	if i == nil {
		logs.Error("issue template is nil")
		return msg, "", false
	}
	ok = true
	tbContent := make([]interface{}, 12)
	if util.TrimString(i.CveAnalysis) == "" || len(util.TrimString(i.CveAnalysis)) < 2 {
		tbContent[0] = "待分析"
		tbContent[1] = "1.影响性分析说明"
		tbContent[2] = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		msg = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		ok = false
	} else {
		tbContent[0] = "已分析"
		tbContent[1] = "1.影响性分析说明"
		tbContent[2] = util.TrimStringNR(i.CveAnalysis)
	}
	affectedVersionFlag := 1
	if i.AffectedVersion != "" {
		versionfFlag := true
		affectedVersionArry := strings.Split(i.AffectedVersion, ",")
		if len(affectedVersionArry) > 0 {
			for _, affect := range affectedVersionArry {
				versionArry := strings.Split(affect, ":")
				if len(versionArry) > 1 {
					if versionArry[1] == "受影响" || versionArry[1] == "不受影响" {
						if versionArry[1] == "受影响" {
							affectedVersionFlag = 2
						}
						continue
					} else {
						affectedVersionFlag = 3
						versionfFlag = false
						break
					}
				} else {
					affectedVersionFlag = 3
					versionfFlag = false
					break
				}
			}
		}
		if !versionfFlag {
			tbContent[9] = "待分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = fmt.Sprintf("3.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			msg = fmt.Sprintf("3.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			ok = false
		} else {
			tbContent[9] = "已分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		}
	} else {
		tbContent[9] = "已分析"
		tbContent[10] = "3.受影响版本排查"
		tbContent[11] = ""
	}
	if affectedVersionFlag == 1 {
		tbContent[3] = "已分析"
		tbContent[4] = "2.openGaussScore"
		tbContent[5] = i.OpenEulerScore
		tbContent[6] = "已分析"
		tbContent[7] = "2.openGaussVector"
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	} else {
		if i.OpenEulerScore == 0.0 {
			tbContent[3] = "待分析"
			tbContent[4] = "2.openGaussScore"
			tbContent[5] = fmt.Sprintf("2.openGaussScore=> 没有填写或正确填写(0-10)")
			msg = fmt.Sprintf("2.openGaussScore=> 没有填写或正确填写(0-10)")
			ok = false
		} else {
			tbContent[3] = "已分析"
			tbContent[4] = "2.openGaussScore"
			tbContent[5] = i.OpenEulerScore
		}
		if util.TrimString(i.OpenEulerVector) == "" || len(util.TrimString(i.OpenEulerVector)) < 1 {
			tbContent[6] = "待分析"
			tbContent[7] = "2.openGaussVector"
			tbContent[8] = fmt.Sprintf("2.openGaussVector=> 没有正确填写")
			msg = fmt.Sprintf("2.openGaussVector=> 没有正确填写")
			ok = false
		} else {
			tbContent[6] = "已分析"
			tbContent[7] = "2.openGaussVector"
			tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
		}
	}
	tbStr = fmt.Sprintf(tb, tbContent...)
	return
}

func checkSporeIssueClosedAnalysisComplete(i *models.IssueTemplate) (msg, tbStr string, ok bool) {
	tb :=
		`| 状态  | 需分析 | 内容 |
|:--:|:--:|---------|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
`
	if i == nil {
		logs.Error("issue template is nil")
		return msg, "", false
	}
	ok = true
	tbContent := make([]interface{}, 12)
	if util.TrimString(i.CveAnalysis) == "" || len(util.TrimString(i.CveAnalysis)) < 2 {
		tbContent[0] = "待分析"
		tbContent[1] = "1.影响性分析说明"
		tbContent[2] = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		msg = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		ok = false
	} else {
		tbContent[0] = "已分析"
		tbContent[1] = "1.影响性分析说明"
		tbContent[2] = util.TrimStringNR(i.CveAnalysis)
	}
	affectedVersionFlag := 1
	if i.AffectedVersion != "" {
		versionfFlag := true
		affectedVersionArry := strings.Split(i.AffectedVersion, ",")
		if len(affectedVersionArry) > 0 {
			for _, affect := range affectedVersionArry {
				versionArry := strings.Split(affect, ":")
				if len(versionArry) > 1 {
					if versionArry[1] == "受影响" || versionArry[1] == "不受影响" {
						if versionArry[1] == "受影响" {
							affectedVersionFlag = 2
						}
						continue
					} else {
						affectedVersionFlag = 3
						versionfFlag = false
						break
					}
				} else {
					affectedVersionFlag = 3
					versionfFlag = false
					break
				}
			}
		}
		if !versionfFlag {
			tbContent[9] = "待分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = fmt.Sprintf("3.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			msg = fmt.Sprintf("3.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			ok = false
		} else {
			tbContent[9] = "已分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		}
	} else {
		tbContent[9] = "已分析"
		tbContent[10] = "3.受影响版本排查"
		tbContent[11] = ""
	}
	if affectedVersionFlag == 1 {
		tbContent[3] = "已分析"
		tbContent[4] = "2.MindSporeScore"
		tbContent[5] = i.OpenEulerScore
		tbContent[6] = "已分析"
		tbContent[7] = "2.MindSporeVector"
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	} else {
		if i.OpenEulerScore == 0.0 {
			tbContent[3] = "待分析"
			tbContent[4] = "2.MindSporeScore"
			tbContent[5] = fmt.Sprintf("2.MindSporeScore=> 没有填写或正确填写(0-10)")
			msg = fmt.Sprintf("2.MindSporeScore=> 没有填写或正确填写(0-10)")
			ok = false
		} else {
			tbContent[3] = "已分析"
			tbContent[4] = "2.MindSporeScore"
			tbContent[5] = i.OpenEulerScore
		}
		if util.TrimString(i.OpenEulerVector) == "" || len(util.TrimString(i.OpenEulerVector)) < 1 {
			tbContent[6] = "待分析"
			tbContent[7] = "2.MindSporeVector"
			tbContent[8] = fmt.Sprintf("2.MindSporeVector=> 没有正确填写")
			msg = fmt.Sprintf("2.MindSporeVector=> 没有正确填写")
			ok = false
		} else {
			tbContent[6] = "已分析"
			tbContent[7] = "2.MindSporeVector"
			tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
		}
	}
	tbStr = fmt.Sprintf(tb, tbContent...)
	return
}

func checkLooKengIssueClosedAnalysisComplete(i *models.IssueTemplate) (msg, tbStr string, ok bool) {
	tb :=
		`| 状态  | 需分析 | 内容 |
|:--:|:--:|---------|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
|%v|%v|%v|
`
	if i == nil {
		logs.Error("issue template is nil")
		return msg, "", false
	}
	ok = true
	tbContent := make([]interface{}, 12)
	if util.TrimString(i.CveAnalysis) == "" || len(util.TrimString(i.CveAnalysis)) < 2 {
		tbContent[0] = "待分析"
		tbContent[1] = "1.影响性分析说明"
		tbContent[2] = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		msg = fmt.Sprintf("1.影响性分析说明=> 没有填写或按正确格式填写")
		ok = false
	} else {
		tbContent[0] = "已分析"
		tbContent[1] = "1.影响性分析说明"
		tbContent[2] = util.TrimStringNR(i.CveAnalysis)
	}
	affectedVersionFlag := 1
	if i.AffectedVersion != "" {
		versionfFlag := true
		affectedVersionArry := strings.Split(i.AffectedVersion, ",")
		if len(affectedVersionArry) > 0 {
			for _, affect := range affectedVersionArry {
				versionArry := strings.Split(affect, ":")
				if len(versionArry) > 1 {
					if versionArry[1] == "受影响" || versionArry[1] == "不受影响" {
						if versionArry[1] == "受影响" {
							affectedVersionFlag = 2
						}
						continue
					} else {
						affectedVersionFlag = 3
						versionfFlag = false
						break
					}
				} else {
					affectedVersionFlag = 3
					versionfFlag = false
					break
				}
			}
		}
		if !versionfFlag {
			tbContent[9] = "待分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = fmt.Sprintf("3.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			msg = fmt.Sprintf("3.受影响版本排查(受影响/不受影响)=> 没有分析或未按正确格式填写:%v", i.AffectedVersion)
			ok = false
		} else {
			tbContent[9] = "已分析"
			tbContent[10] = "3.受影响版本排查"
			tbContent[11] = util.TrimStringNR(i.AffectedVersion)
		}
	} else {
		tbContent[9] = "已分析"
		tbContent[10] = "3.受影响版本排查"
		tbContent[11] = ""
	}
	if affectedVersionFlag == 1 {
		tbContent[3] = "已分析"
		tbContent[4] = "2.openLooKengScore"
		tbContent[5] = i.OpenEulerScore
		tbContent[6] = "已分析"
		tbContent[7] = "2.openLooKengVector"
		tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
	} else {
		if i.OpenEulerScore == 0.0 {
			tbContent[3] = "待分析"
			tbContent[4] = "2.openLooKengScore"
			tbContent[5] = fmt.Sprintf("2.openLooKengScore=> 没有填写或正确填写(0-10)")
			msg = fmt.Sprintf("2.openLooKengScore=> 没有填写或正确填写(0-10)")
			ok = false
		} else {
			tbContent[3] = "已分析"
			tbContent[4] = "2.openLooKengScore"
			tbContent[5] = i.OpenEulerScore
		}
		if util.TrimString(i.OpenEulerVector) == "" || len(util.TrimString(i.OpenEulerVector)) < 1 {
			tbContent[6] = "待分析"
			tbContent[7] = "2.openLooKengVector"
			tbContent[8] = fmt.Sprintf("2.openLooKengVector=> 没有正确填写")
			msg = fmt.Sprintf("2.openLooKengVector=> 没有正确填写")
			ok = false
		} else {
			tbContent[6] = "已分析"
			tbContent[7] = "2.openLooKengVector"
			tbContent[8] = util.TrimStringNR(i.OpenEulerVector)
		}
	}
	tbStr = fmt.Sprintf(tb, tbContent...)
	return
}

func commentUpdateIssue(issueTmp models.IssueTemplate, owner, accessToken, path string) {
	if accessToken != "" && owner != "" && path != "" {
		cvlnCenter := models.VulnCenter{}
		err := models.GetVulnCenterByCVEID(&cvlnCenter, issueTmp.CveId)
		if err != nil {
			logs.Error("GetVulnCenterByCVEID, err: ", err, ",cvlnCenter: ", cvlnCenter)
		} else {
			_, err := taskhandler.UpdateIssueToGit(accessToken, owner, path, cvlnCenter, issueTmp)
			if err != nil {
				logs.Error("UpdateIssueToGit, upErr: ", err, ",issueTmp: ", issueTmp)
			}
		}
	}
}

func saveVectorData(vct string, cveID int64) error {
	score, err := models.QueryIssueScore(cveID)
	if err != nil {
		return err
	}
	if vct == "" {
		return errors.New("vct value is empty")
	}
	upFields := make([]string, 0)
	score.OvectorVule = vct
	upFields = append(upFields, "o_vector_value")
	vMap, ok := util.VctToMap(vct)
	if !ok {
		return errors.New("vector value illegal")
	}
	if util.RegexpVectorV2.Match([]byte(vct)) {
		//update v2 vector
		avv := util.ReadVMValueV2(vMap["AV"])
		if avv != "" {
			score.OaccessVector = avv
			upFields = append(upFields, "o_access_vector")
		}
		acv := util.ReadVMValueV2(vMap["AC"])
		if acv != "" {
			score.OaccessComplexity = acv
			upFields = append(upFields, "o_access_complexity")
		}
		au := util.ReadVMValueV2(vMap["Au"])
		if au != "" {
			score.Oauthentication = au
			upFields = append(upFields, "o_authentication")
		}
		cv := util.ReadVMValueV2(vMap["C"])
		if cv != "" {
			score.Oconfidentiality = cv
			upFields = append(upFields, "o_confidentiality")
		}
		iv := util.ReadVMValueV2(vMap["I"])
		if iv != "" {
			score.Ointegrity = iv
			upFields = append(upFields, "o_integrity")
		}
		av := util.ReadVMValueV2(vMap["A"])
		if av != "" {
			score.Oavailability = av
			upFields = append(upFields, "o_availability")
		}
	} else {
		//update v3 vector
		avv := util.ReadVMValue(vMap["AV"])
		if avv != "" {
			score.OattackVector = avv
			upFields = append(upFields, "o_attack_vector")
		}
		acv := util.ReadVMValue(vMap["AC"])
		if acv != "" {
			score.OattackComplexity = acv
			upFields = append(upFields, "o_attack_complexity")
		}
		prv := util.ReadVMValue(vMap["PR"])
		if prv != "" {
			score.OprivilegeRequired = prv
			upFields = append(upFields, "o_privilege_required")
		}
		uiv := util.ReadVMValue(vMap["UI"])
		if uiv != "" {
			score.OuserInteraction = uiv
			upFields = append(upFields, "o_user_interaction")
		}
		sv := util.ReadVMValue(vMap["S"])
		if sv != "" {
			score.Oscope = sv
			upFields = append(upFields, "o_scope")
		}
		cv := util.ReadVMValue(vMap["C"])
		if cv != "" {
			score.Oconfidentiality = cv
			upFields = append(upFields, "o_confidentiality")
		}
		iv := util.ReadVMValue(vMap["I"])
		if iv != "" {
			score.Ointegrity = iv
			upFields = append(upFields, "o_integrity")
		}
		av := util.ReadVMValue(vMap["A"])
		if av != "" {
			score.Oavailability = av
			upFields = append(upFields, "o_availability")
		}
	}
	if len(upFields) > 0 {
		//Perform update
		err = models.UpdateScore(&score, upFields...)
		if err != nil {
			return err
		}
	}
	return nil
}

func handleCommentPackage(packageStr string, cveID int64) error {
	packageStr = util.TrimString(packageStr)
	err := models.UpdatePackageByCveId(packageStr, cveID)
	if err != nil {
		return err
	}
	return nil
}

//CloseIssue close gitee issue
func CloseIssue(token, repo, issueNum, owner string) bool {
	url := fmt.Sprintf("https://gitee.com/api/v5/repos/%s/issues/%s", owner, issueNum)
	param := struct {
		AccessToken string `json:"access_token"`
		Repo        string `json:"repo"`
		State       string `json:"state"`
	}{token, repo, "closed"}
	pj, err := json.Marshal(&param)
	if err != nil {
		logs.Error("json.Marshal, err:", err, ",issueNum: ", issueNum)
		return false
	}
	return UpdateGiteIssue(url, pj)
}

//UpdateGiteIssue update gitee issue
func UpdateGiteIssue(url string, param []byte) bool {
	read := bytes.NewReader(param)
	req, err := http.NewRequest(http.MethodPatch, url, read)
	if err != nil {
		logs.Error("NewRequest, err:", err)
		return false
	}
	defer req.Body.Close()
	req.Header.Set("Content-Type", "application/json;charset=UTF-8")
	client := http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		logs.Error("client.Do, err:", err)
		return false
	}
	defer resp.Body.Close()
	if resp.StatusCode == 200 {
		return true
	}
	return false
}

func AddGitIssue(issueHook *models.IssuePayload, desc, product string) error {
	issueTitle := util.TrimString(issueHook.Title)
	issueType := util.TrimString(issueHook.Issue.TypeName)
	issueNumber := util.TrimString(issueHook.Issue.Number)
	issueState := util.TrimString(issueHook.Issue.State)
	issueZhState := util.TrimString(issueHook.Issue.StateName)
	repoPath := util.TrimString(issueHook.Repository.Path)
	nameSpace := util.TrimString(issueHook.Repository.NameSpace)
	organizationID := int8(1)
	organizationID = taskhandler.GetOrganizationId(nameSpace)
	issueTitle = taskhandler.RegMatchCve(issueTitle)
	if issueType == CIssueType || strings.HasPrefix(issueTitle, "CVE") {
		item := models.GiteOriginIssue{IssueId: issueHook.Issue.Id, Url: issueHook.Issue.HtmlUrl,
			Number: issueNumber, State: issueState, Title: issueTitle,
			IssueType: issueType, SecurityHole: true,
			IssueCreateAt: issueHook.Issue.CreateAt, IssueUpdateAt: issueHook.Issue.UpdateAt,
			IssueFinishAt: issueHook.Issue.FinishedAt, IssueCreate: issueHook.Issue.User.Login,
			IssueAssignee: issueHook.Assignee.Login, RepoPath: repoPath,
			RepoUrl: issueHook.Repository.Url, InfProduct: product,
			RepoDesc: desc, IssueState: issueZhState, Owner: nameSpace, OrganizationID: organizationID,
			Status: 0}
		//vt := util.TrimString(v.Title)
		cveStr := ""
		if strings.HasPrefix(issueTitle, "CVE") {
			cveStr = issueTitle
		} else if issueHook.Issue.Body != "" {
			// Use regular expressions to intercept the body, which will be improved later
			sm := util.RegexpCveNumber.FindAllStringSubmatch(issueHook.Issue.Body, -1)
			if len(sm) > 0 && len(sm[0]) > 0 {
				cveStr = sm[0][1]
			}
		}
		cveList := []string{}
		if len(cveStr) > 1 {
			cveRes := util.RegexpCveNumVaule.FindAllStringSubmatch(cveStr, -1)
			if len(cveRes) > 0 {
				for _, cr := range cveRes {
					if len(cr) > 0 {
						tCr := util.TrimString(cr[0])
						if _, ok := common.FindSliceEm(cveList, tCr); !ok {
							cveList = append(cveList, tCr)
						}
					}
				}
			}
		}
		owner, accessToken := common.GetOwnerAndToken(organizationID)
		for _, cve := range cveList {
			item.CveNumber = cve
			// Check whether the current cve has created an issue
			checkRes := taskhandler.OPenCheckWhetherIssue(item.CveNumber, repoPath, owner, accessToken, organizationID)
			if checkRes {
				logs.Error("Cve has created an issue, please process the previous issue first, ",
					item.CveNumber, repoPath, ", organizationID: ", organizationID)
				taskhandler.AddCommentToIssue(fmt.Sprintf(HasCreateIssue, issueHook.Assignee.UserName, item.CveNumber),
					issueNumber, owner, repoPath, accessToken)
				return errors.New("Ignore the current issue")
			}
			//vb := util.TrimString(v.Body)
			vb := strings.ReplaceAll(issueHook.Issue.Body, "：", ":")
			item.Body = vb
			item.IssueExistTpl = false
			err := item.InsertOrUpdate(2)
			if err != nil {
				logs.Error("insert or update issue fail:", err)
			}
		}
		return nil
	} else {
		return errors.New("Ignore the current issue")
	}
}

func DelOrgIssue(issueHook *models.IssuePayload, organizationID int8) {
	issueTitle := util.TrimString(issueHook.Title)
	issueType := util.TrimString(issueHook.Issue.TypeName)
	issueNumber := util.TrimString(issueHook.Issue.Number)
	issueState := util.TrimString(issueHook.Issue.State)
	issueZhState := util.TrimString(issueHook.Issue.StateName)
	repoPath := util.TrimString(issueHook.Repository.Path)
	nameSpace := util.TrimString(issueHook.Repository.NameSpace)
	organizationID = taskhandler.GetOrganizationId(nameSpace)
	issueTitle = taskhandler.RegMatchCve(issueTitle)
	if issueType == CIssueType || strings.HasPrefix(issueTitle, "CVE") {
		// Data deletion record
		idr := models.IssueDeleteRecord{IssueId: issueHook.Issue.Id, IssueNum: issueNumber,
			DelAssignee: issueHook.Sender.Login, Owner: nameSpace, Repo: repoPath,
			DeleteTime: common.GetCurTime(), OrganizationID: organizationID, CveNum: issueTitle}
		models.InsertIssueDeleteRecord(&idr)
		item := models.GiteOriginIssue{IssueId: issueHook.Issue.Id, Url: issueHook.Issue.HtmlUrl,
			Number: issueNumber, State: issueState, Title: issueTitle,
			IssueType: issueType, SecurityHole: true,
			IssueCreateAt: issueHook.Issue.CreateAt, IssueUpdateAt: issueHook.Issue.UpdateAt,
			IssueFinishAt: issueHook.Issue.FinishedAt, IssueCreate: issueHook.Issue.User.Login,
			IssueAssignee: "", RepoPath: repoPath,
			RepoUrl: issueHook.Repository.Url, InfProduct: "",
			RepoDesc: "", IssueState: issueZhState, Owner: nameSpace, OrganizationID: organizationID}
		if strings.HasPrefix(issueTitle, "CVE") {
			item.CveNumber = issueTitle
		} else if issueHook.Issue.Body != "" {
			// Use regular expressions to intercept the body and improve it later
			sm := util.RegexpCveNumber.FindAllStringSubmatch(issueHook.Issue.Body, -1)
			if len(sm) > 0 && len(sm[0]) > 0 {
				item.CveNumber = util.TrimString(sm[0][1])
			}
		}
		err := item.Detlete()
		if err != nil {
			logs.Error("Failed to delete issue:", err)
		}
		issueTmp := models.IssueTemplate{}
		issueTmp.IssueId = issueHook.Issue.Id
		issueTmp.IssueNum = issueNumber
		issueTmp.Repo = repoPath
		issueErr := models.GetIssueTemplateByColName(&issueTmp, "IssueNum", "Repo", "IssueId")
		if issueErr != nil {
			return
		}
		issueTmp.Status = 6
		issueTmp.IssueStatus = 6
		issueTmp.StatusName = "已删除"
		tpErr := models.UpdateIssueTemplate(&issueTmp, "status", "issue_status",
			"status_name")
		if tpErr != nil {
			logs.Error("UpdateIssueTemplate, tpErr:", tpErr, ",issueTmp: ", issueTmp)
		}
		cveCenter := models.VulnCenter{CveId: issueTmp.CveId, CveNum: issueTmp.CveNum, PackName: issueTmp.Repo}
		cveErr := models.GetVulnCenterByCid(&cveCenter, "cve_id", "cve_num", "pack_name")
		if cveErr != nil {
			return
		}
		cveCenter.Status = 7
		update := models.UpdateVulnCenter(&cveCenter, "cve_status")
		if !update {
			logs.Error("update vulnCenter fail ")
		}
	}
}

// Entry function for handling issue status
func gitAddIssueProc(issueHook *models.IssuePayload, organizationID int8) error {
	owner, token := common.GetOwnerAndToken(organizationID)
	path := issueHook.Repository.Path
	// The amount of data processed at a time
	prcNum, err := beego.AppConfig.Int("crontab::prcnum")
	if err != nil {
		logs.Error("crontab::prcnum, error:  ", err)
		return errors.New("value is nil")
	}
	// How many days have been processed to date data
	days, ok := beego.AppConfig.Int("crontab::days")
	if ok != nil {
		logs.Error("crontab::days, err:", err)
		return ok
	}
	// openeuler Number start value
	cveRef := beego.AppConfig.String("cve::cveref")
	openeulerNum, ok := beego.AppConfig.Int("cve::openeulernum")
	if ok != nil {
		logs.Error("cve::openeulernum, err:", err)
		return ok
	}
	// Determine whether the issue has been created
	product, err := taskhandler.GetInfProduct(token, owner, path)
	if err != nil {
		logs.Error("GetInfProduct, err: ", err)
	}
	desc := taskhandler.GetRepoDescription(path)
	giErr := AddGitIssue(issueHook, desc, product)
	if giErr != nil {
		logs.Error("AddGitIssue, giErr: ", giErr)
	}
	// Compatible with created issue data
	oki, err := taskhandler.GetCveIssueData(prcNum, days, openeulerNum, cveRef, owner, 1)
	if !oki {
		logs.Error("ProcCveOriginData, GetCveIssueData, err: ", err)
	}
	cError := task.CreateIssue()
	if cError != nil {
		logs.Error("CreateIssue, cError: ", cError)
	}
	comErr := AddIssueComment(token, owner, path, issueHook.Issue.Number,
		issueHook.Issue.User.UserName, issueHook.Issue.Id)
	logs.Info("CreateIssueToGit, Issue comment creation result, err: ", comErr)
	return comErr
}

func AddIssueComment(token, owner, path, issueNum, assignee string, issueId int64) error {
	// Create the first comment
	branchList := []string{}
	errBrands := errors.New("")
	issueTmp := models.IssueTemplate{}
	issueTmp.IssueId = issueId
	issueTmp.IssueNum = issueNum
	issueTmp.Repo = path
	issueErr := models.GetIssueTemplateByColName(&issueTmp, "IssueNum", "Repo", "IssueId")
	if issueErr != nil {
		logs.Error("GetIssueTemplateByColName, err: ", issueErr, ", issue: ", issueTmp)
		return issueErr
	}
	cveCenter := models.VulnCenter{CveId: issueTmp.CveId, CveNum: issueTmp.CveNum, PackName: path}
	cveErr := models.GetVulnCenterByCid(&cveCenter, "cve_id", "cve_num", "pack_name")
	if cveErr != nil {
		return cveErr
	}
	owner, token = common.GetOwnerAndToken(cveCenter.OrganizationID)
	if cveCenter.OrganizationID == 4 {
		cveList := strings.Split(cveCenter.CveVersion, ",")
		if len(cveList) > 0 {
			for _, vl := range cveList {
				olky := models.OpenLookengYaml{PackageName: cveCenter.RepoName, Version: vl, Repo: cveCenter.PackName}
				looKengErr := models.GetOpenLookengYaml(&olky, "PackageName", "Version", "Repo")
				if olky.Id > 0 {
					path = olky.Repo
					break
				}
				logs.Info("GetOpenLookengYaml, looKengErr: ", looKengErr)
			}
		}
		branchList = taskhandler.CreateBrandAndTags(token, owner, path, cveCenter.OrganizationID)
		if branchList == nil || len(branchList) == 0 {
			logs.Error("OpenLookeng GetBranchesInfo, Failed to obtain the branch information of the repo, ", path, ", err: ", errBrands)
			return errors.New("Failed to obtain branch information")
		}
	} else if cveCenter.OrganizationID == 3 {
		// Query the repo that needs to submit an issue
		cveList := strings.Split(cveCenter.CveVersion, ",")
		if len(cveList) > 0 {
			for _, vl := range cveList {
				ms := models.MindSporeYaml{PackageName: cveCenter.RepoName, Version: vl, Repo: cveCenter.PackName}
				sporeErr := models.GetMindSporeYaml(&ms, "PackageName", "Version", "Repo")
				if ms.Id > 0 {
					path = ms.Repo
					break
				}
				logs.Info("GetMindSporeYaml, sporeErr: ", sporeErr)
			}
		}
		// Get branch information
		branchList = taskhandler.CreateBrandAndTags(token, owner, path, cveCenter.OrganizationID)
		if branchList == nil || len(branchList) == 0 {
			logs.Error("mindspore GetBranchesInfo, "+
				"Failed to obtain the branch information of the repo: ", path, ", err: ", errBrands)
			return errors.New("Failed to obtain branch information")
		}
	} else if cveCenter.OrganizationID == 2 {
		path = beego.AppConfig.String("opengauss::openGauss-server")
		// Get branch information
		branchList, errBrands = taskhandler.GetBranchesInfo(token, owner, path, cveCenter.OrganizationID)
		if branchList == nil || len(branchList) == 0 {
			logs.Error("Gauss GetBranchesInfo, Failed to obtain the branch information of the repo, ", path, ", err: ", errBrands)
			return errors.New("Failed to obtain branch information")
		}
	} else {
		// Get branch information
		branchList, errBrands = taskhandler.GetBranchesInfo(token, owner, path, cveCenter.OrganizationID)
		if branchList == nil || len(branchList) == 0 {
			logs.Error("Euler GetBranchesInfo, Failed to obtain the branch information of the repo, ", path, ", err: ", errBrands)
			return errors.New("Failed to obtain branch information")
		}
	}
	// Create issue comment
	affectedVersion := ""
	if len(branchList) > 0 {
		for i, brand := range branchList {
			if brand == "" || len(brand) < 2 {
				continue
			}
			brandx := ""
			if cveCenter.OrganizationID == 1 {
				brandx = common.BranchVersionRep(brand)
				brandx = taskhandler.OrgRepoParams(cveCenter.PackName, brandx)
			} else {
				brandx = brand
			}
			affectedVersion = affectedVersion + strconv.Itoa(i+1) + "." + brandx + ":\n"
		}
	} else {
		affectedVersion = affectedVersion + "\n"
	}
	_, assignLoginList, _ := taskhandler.GetRepoMember(token, owner, path)
	errx := taskhandler.CreateIssueComment(token, owner, path, assignee,
		cveCenter, issueNum, affectedVersion, assignLoginList)
	return errx
}

func gitDelIssueProc(issueHook *models.IssuePayload, organizationID int8) error {
	DelOrgIssue(issueHook, organizationID)
	return nil
}
